交差監視: IntersectionObserver

IntersectionObserver API を使うと「お、この要素見える位置に入ってきたな」と分かったときに好きな処理を行えます。

これを使うにはまずインスタンスを作ります。

const observer = IntersectionObserver(callback, {/* ... */});

ここで渡したcallbackは(デフォルトで)ブラウザ画面に要素が入ってきたり、出ていったとこに発火されるコールバック関数です。この関数は引数にIntersectionObserverEntryの配列を渡してきます。この値は出たり入ったりした要素と様々なコンテキストを持ったオブジェクトです。
例えばintersectionRatioはコンテキストの1つで、0-1の間(小数点含む)の値で対象の要素は今どれだけ可視領域に入ってるのかが分かります。これは0だとすべて見えてない、1だとすべて見えてるという意味になるからです。

設定

先程デフォルトでと書きましたが、どの要素を基準に出たり入ったりを監視するかは変えることができます。これにはIntersectionObserverの第2引数を使います。第2引数には基準を変える以外の要素も持っています。

root

rootが要素の基準になるものです。これはデフォルトではブラウザのビューポートになってますが、

{
  root: document.getElementById('container')
}

とすると、そのobserverで監視した要素は#containerから出たり入ったりした時にコールバックが走るようになります。

rootMargin

rootMarginroot要素の領域を拡大・縮小化できます。例えばrootMargin: '50px 50px 50px 50px'とした場合、要素の見た目は変わりませんが、上右下左側に50px余分に自分の可視領域だと見なすことができます。つまり、observeしている要素が表示領域まで達するのに実際はあと50pxあったとしてもコールバック関数が発火します。

この値を例えば-50pxとすると逆の意味になります。-50pxと設定されていると実際に見えるようになった領域から更に50pxスクロールしなければコールバックが発火しなくなります。

このオプションはデフォルトで0px 0px 0px 0pxが設定されてます。

threshold

thresholdはどれくらいの頻度でコールバックを呼び出すかを設定します。デフォルトでは0が設定されてます。これは(rootMarginがすべて0の状態で)1pxでも被った時コールバック関数を実行するということになります。

この値を0.5に変えると要素が半分見えた時にコールバック関数が発火するようになり、1だとすべて見えた時…という具合になります。

この値は配列でも設定することができ、[0, 0.5, 1]と設定すれば、入る時は

  1. 1pxでも見えた時
  2. 半分見えた時
  3. 全部見えた時

出る時は

  1. 全部見えなくなった時
  2. 半分見えなくなった時
  3. まったく見えなくなった時

という具合でコールバック関数が呼ばれるようになります。

要素の監視

監視を始めるにはIntersectionObserver#observeを呼びます。この引数には監視対象となる要素を渡します。

observer.observe(element);

監視の必要が無ければ解除しましょう。それにはIntersectionObserver#unobserveまたはIntersectionObserver#disconnectを使います。前者は要素1つに関して監視を解除するメソッドですが、後者はそのオブザーバーの監視対象すべてについて解除します。

observer.observe(element);
observer.disconnect();