DOM 要素 (HTML ドキュメント内) が現在表示されているかどうか (ビューポートに表示されているかどうか)を確認する効率的な方法はありますか?
(質問は Firefox に関するものです。)
ベストアンサー1
今ほとんどのブラウザサポート取得バウンディングクライアント矩形ベストプラクティスとなった方法です。古い回答を使うのは非常に遅く、正確ではないそしていくつかのバグがある。
正解として選ばれた解決策はほとんど正確ではない。
このソリューションは、Internet Explorer 7(以降)、iOS 5(以降)、Safariでテストされています。アンドロイド 2.0(Eclair) 以降、BlackBerry、Opera Mobile、Internet Explorer Mobile9。
function isElementInViewport (el) {
// Special bonus for those using jQuery
if (typeof jQuery === "function" && el instanceof jQuery) {
el = el[0];
}
var rect = el.getBoundingClientRect();
return (
rect.top >= 0 &&
rect.left >= 0 &&
rect.bottom <= (window.innerHeight || document.documentElement.clientHeight) && /* or $(window).height() */
rect.right <= (window.innerWidth || document.documentElement.clientWidth) /* or $(window).width() */
);
}
使い方:
上記の関数は、呼び出された瞬間に正しい答えを返すことは間違いありませんが、要素の可視性をイベントとして追跡する場合はどうでしょうか?
タグの下部に次のコードを配置します<body>
。
function onVisibilityChange(el, callback) {
var old_visible;
return function () {
var visible = isElementInViewport(el);
if (visible != old_visible) {
old_visible = visible;
if (typeof callback == 'function') {
callback();
}
}
}
}
var handler = onVisibilityChange(el, function() {
/* Your code go here */
});
// jQuery
$(window).on('DOMContentLoaded load resize scroll', handler);
/* // Non-jQuery
if (window.addEventListener) {
addEventListener('DOMContentLoaded', handler, false);
addEventListener('load', handler, false);
addEventListener('scroll', handler, false);
addEventListener('resize', handler, false);
} else if (window.attachEvent) {
attachEvent('onDOMContentLoaded', handler); // Internet Explorer 9+ :(
attachEvent('onload', handler);
attachEvent('onscroll', handler);
attachEvent('onresize', handler);
}
*/
もちろん、DOM を変更すると、要素の可視性も変更される可能性があります。
ガイドラインとよくある落とし穴:
ページのズームやモバイルデバイスのピンチを追跡する必要があるかもしれませんか? jQueryで処理できますズーム/ピンチクロスブラウザ、それ以外初めまたは2番リンクが役に立つはずです。
DOM を変更すると、要素の可視性に影響する可能性があります。その制御を行い、handler()
手動で呼び出す必要があります。残念ながら、クロスブラウザ イベントはありませんonrepaint
。その一方で、要素の可視性を変更する可能性のある DOM の変更に対してのみ最適化を行い、再チェックを実行できます。
jQuery内では絶対に使用しないでください$(ドキュメント).ready()ただ、なぜならCSSが適用されているという保証はありません現時点では、コードはハードドライブ上の CSS でローカルに動作しますが、リモート サーバーに配置すると動作しなくなります。
解雇された後DOMContentLoaded
、スタイルが適用される、 しかし画像はまだ読み込まれていませんしたがって、window.onload
イベント リスナーを追加する必要があります。
ズーム/ピンチイベントをまだキャッチできません。
最後の手段としては、次のコードが考えられます。
/* TODO: this looks like a very bad code */
setInterval(handler, 600);
素晴らしい機能を使うことができますページ表示Web ページのタブがアクティブで表示されているかどうかを気にする場合は、HTML5 API を使用します。
TODO: このメソッドは次の 2 つの状況を処理しません:
- 使用して重複します
z-index
。 overflow-scroll
要素のコンテナー内で使用します。- 何か新しいことに挑戦します -Intersection Observer APIの説明。