PlusOne Blog

【JavaScript】Intersection Observer API

画像の遅延ロードを作成しているとき、
Intersection Observer API について、調べてみたので、備忘録として。
 
Intersection Observer API とは、交差監視APIと言われ、任意の要素が表示画面内に現れるかどうかを監視・判定する API です。
引用:https://developer.mozilla.org/ja/docs/Web/API/Intersection_Observer_API
 

Intersection obserer の作成

コンストラクターを呼び出して Intersection observer を作成し、閾値が一方向また他の方向に交差する度に実行されるコールバック関数を渡します。

  let options = {
    root: document.querySelector('#scrollArea'),
    rootMargin: '0px',
    threshold: 1.0
  }

  let observer = new IntersectionObserver(callback, options);

■Intersection observer のオプション
コンストラクタに渡された options オブジェクトは、オブザーバーのコールバックが呼び出される状況を制御し、以下のフィールドがあります:
 
root:ターゲットが見えるかどうかを確認するためのビューポートとして使用される要素です。指定されなかった場合、もしくは null の場合はデフォルトでブラウザーのビューポートが使用されます。
 
rootMargin:root の周りのマージンです。CSS margin プロパティに似た値を持つことができます。例えば、”10px 20px 30px 40px” (top, right, bottom, left) のようなものです。この値はパーセント値にすることができます。この一連の値は、交差を計算する前にルート要素の範囲のボックスの各辺を拡大または縮小させることができます。既定ではすべてゼロです。
 
threshold:単一の数値もしくは数値の配列で、オブザーバーのコールバックを実行するターゲットがどのくらいの割合で見えているかを示します。 50% 通過したときのみ検出する場合は値 0.5 を使用します。 25% を超える度にコールバックを実行する場合は、 [0, 0.25, 0.5, 0.75, 1] という配列を指定します。既定値は 0 です (つまり、1ピクセルでも表示されるとコールバックが実行されます)。1.0 の値は全てのピクセルが見えるようになるまで、閾値をまたいだとみなされないことを意味します。
 

監視される要素をターゲットにする

  var target = document.querySelector('#listItem');
  observer.observe(target);

ターゲットが IntersectionObserver に指定された閾値を満たす度にコールバックが呼び出されます。コールバックは IntersectionObserverEntry オブジェクトのリストとオブザーバーを受け取ります。
 

交差しているかどうかの判定

変更の通知を受ける時にコールバック関数に渡された IntersectionObserverEntry の isIntersecting プロパティの値をチェックすることで、変更が感知された方向 (つまり要素が見えたかどうかを) 判断することが出来ます。
isIntersecting が true であれば、ターゲットは閾値を超えて少なくとも見るようになったということですし、false であればターゲットは指定した閾値では表示されなくなったということです。

 intersectionCallback(entries) => {
   entries.forEach(entry => {
     if (entry.isIntersecting) {
       let elem = entry.isIntersecting;
   }
  });
 }

 

例)画像が画面に表示された時にロードする の作成

  document.addEventListener("DOMContentLoaded", function() {

    //Intersection obserer の作成
   let options = {
    root: null,
    rootMargin: '0px',
    threshold: 0
   }
   imageobserver = new IntersectionObserver((entries) => {
    entries.forEach((entry) =>  {
     if (entry.isIntersecting) {
      let image = entry.target;
      image.src = image.dataset.src;
      imageobserver.unobserve(image);
     }
    });
   },options);

   //監視される要素をターゲットにする
   let images = [].slice.call(document.querySelectorAll('.lazyload'));
   images.forEach(function(image) {
    imageobserver.observe(image);
   });
  
  });

 
 

 

この記事を読む
記事一覧に戻る