以前は、要素が表示されているかどうか、または 2 つの要素が交差しているかどうかを検出するのは簡単ではありませんでした。たとえば、画像の遅延読み込みやコンテンツの無限スクロールなどの機能を実装する場合、getBoundingClientRect() を介して大量の論理計算を記述するか、スクロール イベント監視などのパフォーマンスの低いメソッドに依存する必要がありました。
IntersectionObserverを利用することで、上記の機能を非常に便利かつ効率的に実現できます。
1. API
// 创建实例
const observer = new IntersectionObserver(callback, option);
// 开始观察element1
observer.observe(element1);
// 开始观察element2
observer.observe(element2);
// 停止观察
observer.unobserve(element);
// 关闭观察器
observer.disconnect();
IntersectionObserver
これはブラウザによってネイティブに提供されるコンストラクターであり、callback
可視性が変更されたときのコールバック関数と構成オブジェクトoption
(このパラメーターはオプション) の 2 つのパラメーターを受け入れます。
コンストラクターの戻り値はオブザーバー インスタンスです。インスタンスobserve
メソッドでは、どの DOM ノードを監視するかを指定できます。複数の DOM ノードを監視する必要がある場合は、observ メソッドを複数回追加できます。
2、コールバックパラメータ
コールバック関数は次の場合に呼び出されます。
- オブザーバーがターゲット要素を初めてリッスンするとき
- ターゲット要素がデバイス ウィンドウまたは他の指定された要素と交差するたびに実行されます。
callback
関数パラメータ ( entries
) は配列であり、各メンバーはIntersectionObserverEntryオブジェクトです。たとえば、2 つの観測オブジェクトの可視性が同時に変化する場合、entries
配列には 2 つのメンバーが含まれます。
IntersectionObserverEntryオブジェクトの各プロパティの意味は次のとおりです。
boundingClientRect
:対象要素の矩形領域に関する情報intersectionRatio
: ターゲット要素の可視比率、つまり、intersectionRect
ターゲットboundingClientRect
要素が完全に表示されている場合1
、完全に不可視である場合の比率以下になります。0
intersectionRect
: ターゲット要素とビューポート(またはルート要素)の交差領域に関する情報rootBounds
: ルート要素の長方形領域の情報、getBoundingClientRect()
メソッドの戻り値、ルート要素がない場合(つまり、ビューポートを基準にして直接スクロールしている場合)に返されます。null
- isIntersecting : ターゲット要素がビューポート (またはルート要素) と交差するかどうか
- isVisible :関連情報はチェックされておらず、テスト後も変更されません
target
: 監視対象の要素は DOM ノード オブジェクトですtime
: 可視性が変化した時刻。ミリ秒単位の高精度タイムスタンプです。
3. オプションオブジェクト
IntersectionObserver
コンストラクターの 2 番目のパラメーターは構成オブジェクトです。以下のプロパティを設定できます。
root:
ターゲットの可視性をチェックするためのルート要素を指定します。ターゲット要素の親要素である必要があります。指定されていない場合、または である場合null
、デフォルトでブラウザ ウィンドウが表示されます。rootMargin
: ルート要素の外側のマージン。CSS の margin プロパティに似ています。threshold
: ターゲット要素とルート要素の間の交差比率。単一の数値または数値の配列を指定できます。たとえば、ターゲット[0, 0.25, 0.5, 0.75, 1]
要素が 0%、25%、50%、75%、または 100% 表示されているときにコールバック関数がトリガーされることを意味します。
4. 注意事項
- IntersectionObserver API は非同期であり、ターゲット要素のスクロールと同期してトリガーされません。
- 登録されたコールバック関数はメインスレッドで実行されるため、この関数の実行速度はできるだけ高速である必要があります。実行する必要がある時間のかかる操作がある場合は、 Window.requestIdleCallback() メソッドを使用することをお勧めします。
5. 例: 無限スクロール
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>IntersectionObserver</title>
</head>
<body style="font-size: 24px;text-align: center">
<div id="container"></div>
<div id="loadMore">加载中...</div>
</body>
<script>
const container = document.querySelector('#container');
const loadMore = document.querySelector('#loadMore');
let index = 0;
const loadItems = (count) => {
[...Array(count).keys()].forEach((key) => {
const p = document.createElement('P');
p.innerHTML = `${key + index}`;
container.appendChild(p)
})
index += count;
}
const observer = new IntersectionObserver((entries) => {
entries.forEach(({ isIntersecting }) => {
if (isIntersecting) {
loadItems(20);
}
})
});
observer.observe(loadMore)
</script>
</html>
無限スクロール(無限スクロール)の実装も非常に簡単です。#loadMore 要素がブラウザー ビューと交差するかどうかを観察し、交差する場合はリストが読み込まれていることを意味し、さらに要素を追加し続けます。
参考: