Observer intersection

14828 ワード

無限スクロール、画像遅延ロードなどを実現するためのObserver交差の使い方を見てみましょう。


この概念はMDNによく現れているので,簡単なコードで実際の動作方法を理解してみましょう.
index.html
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Document</title>
    <style>
      .root {
        width: 300px;
        height: 500px;
        overflow: scroll;
        border: 5px solid pink;
      }

      li {
        width: 100%;
        height: 200px;
        background-color: grey;
        margin-bottom: 5px;
      }

      .vertical {
        color: white;
        font: 32px "Arial";
      }
    </style>
  </head>
  <body>
    <div class="root">
      <div class="list">
        <li>아이템1</li>
        <li>아이템2</li>
        <li>아이템3</li>
        <li>아이템4</li>
        <li>아이템5</li>
        
      </div>
    </div>
  </body>
  <script src="./index.js"></script>
</html>
index.js
const root = document.querySelector(".root");

const options = {
  root: root, // .root class를 가진 엘리먼트를 감시범위로 설정. null일 경우 브라우저 viewport 범위가 됩니다. 
  threshold: 1, // 타겟 엘리먼트(감시대상)가 감시범위(root요소)의 교차영역에 진입했을 때 ,타켓 엘리먼트의 100%가 감지될때 observe가 반응한다.
};

const observer = new IntersectionObserver(function (entries, observer) {
  console.log(entries)
  console.log(`변화가 감지되었습니다! 감지된 갯수:${entries.length}`);
  entries.forEach((entry) => {
    console.log(entry)
    
  });
}, options);

const childs = document.querySelectorAll("li");
childs.forEach((el) => observer.observe(el));

// 스크롤을 내리면서, observer 범위에서 사라지는것들은 intersection: false로 변함.
最後の行でli要素をすべて登録しました.

  • イニシャルアクション
    監視登録は、最初のobserverオブジェクトを初期化すると、登録されたすべての監視オブジェクトのobserverEntryオブジェクトをentires配列に挿入し、コールバックを実行します.
    各ObserverEntryオブジェクトを開くと、現在の指定範囲内の要素の画面上のステータス(isInterSecting)を表示できます.

  • 初期化された動作
    登録されているすべてのli要素を含むobserverEntryオブジェクトが初期初期化されるため、forEachは数でバイパスされますが、その後、ステータス変更(isInterSectingの変更)に基づいて、変更が検出された要素のみがエントリに含まれるobserverEntryオブジェクトが呼び出されます.
  • すなわち,傍観者が一度初期化した後に次のコールバックを呼び出すと,エントリ配列には変化するエントリオブジェクトのみが含まれる.
    写真を見てみましょう.

    1.observer.observeを使用して監視を開始し、最初のレンダリングを開始する場合



    liオブジェクトが画面に表示されるかどうかにかかわらず、エントリには監視されているすべてのObserverEntryオブジェクトが含まれます.

    ObserverEntryオブジェクトを1~1個表示



    その中で私たちが興味を持っているisIntersection属性を確認しました.

    2.画面をスクロールして、最初の要素を軽く隠します。



    thresholdが1に指定されているため、li要素が完全に隠されているか、表示時にコールバックが呼び出されます.下にスクロールするときに、アイテム1を軽く隠し、すぐにentries配列に配置して、コールバックが呼び出されることを確認できます.

    現在、[プロジェクト1](Project 1)のインタリーブ状態のみが変更されているため、エントリ配列にObserverEntryオブジェクトがあることを確認できます.
    isIntersection値もtrue->falseに変わります.
    なお、thresholdは1であるため、物品3の硬直状態は検出されていない.

    さらに下にスクロールしてアイテム3を表示します。


    さらに下にスクロールすると、システムはコールバックを呼び出し、アイテム3のObserverEntryオブジェクトをentriesとします.
  • で注意すべき点を再度スクロールしてアイテム1を表示すると、アイテム1 ObserverEntryオブジェクトがアイテム配列に入ります.したがって、上記のターゲットを繰り返し検出したくない場合は、forEach文でObserverを使用します.監視状態からunobserver()で除外する必要があります.
  • これは、スクロールイベントの記録やスクロール位置の計算よりもずっと簡単です.
    レンダリングの利点は、ロールバック計算を行わないことです.
    次に,それを用いて反応器中で無限にスクロールするコードを見てみよう.