IntersectionObserverを使うときのテンプレート

IntersectionObserverって使いたくても記述長くて面倒。。

しんぺー

使いやすい雛形を共有しますね。

完成形のイメージ

スクロールして見出しが表示されると、文字がランダムに表示されるようにしています。
今回はTextillateというライブラリを使用していますが、独自でCSSを書いてでふわっと表示させたり色々応用できると思います。

See the Pen intersectionObserver & textillate by shimpei (@shimpei) on CodePen.

IntersectionObserverの雛形

全体像

const Items = document.querySelectorAll(".item");

const options = {
  root: null,
  rootMargin: "0% 0px",
  threshold: 1,
};

const observer = new IntersectionObserver((entries) => {
  entries.forEach((entry) => {
    if (entry.isIntersecting) {
      $(entry.target).textillate({
        in: {
          effect: "fadeInUp",
          shuffle: true,
          delay: 50,
          delayScale: 3,
        }
      });
    } else {
      alert('hey')
    }
  });
}, options);

Items.forEach((item) => {
  observer.observe(item);
});

監視する対象の要素を指定します

.itemという要素を監視します。
こいつが画面に表示された時に、何かしらアクションを起こせます。

querySelectorAllで取得することで複数ある場合の指定がしやすいです。

const Items = document.querySelectorAll(".item");

オプション(発火のタイミングを微調整できます)

const options = {
  root: null,
  rootMargin: "0% 0px",
  threshold: 1,
};
  • root: ターゲットが見えるかどうかをチェックする場所。デフォルトはブラウザーのビューポート。
  • rootMargin: root要素の周囲に適用されるマージン。。
    • CSSのmarginプロパティと似てる(pxや%など単位を書かないと怒られる)。
  • threshold: ターゲットがどのくらい見えているかを判断する基準。

.itemが画面に入ったときに実行するもの

if (entry.isIntersecting){}この中に.itemが見えたときの処理を書いています。
今回はTextillateで文字をランダム表示させています。
クラスのつけ外しをしてCSSを動きをつけるなどが単純で使いやすいかもです。
else{}.itemが画面外に出たときに実行されます。今回は特になにもしていません。

先程指定したoptionsを渡す。ここに直接optionsの内容を書いても大丈夫です。

const observer = new IntersectionObserver((entries) => {
  entries.forEach((entry) => {
    if (entry.isIntersecting) {
      $(entry.target).textillate({
        in: {
          effect: "fadeInUp",
          shuffle: true,
          delay: 50,
          delayScale: 3,
        }
      });
    } else {}
  });
}, options);

長いし訳わからないよ〜書いてられない。

しんぺー

記述がややこしくて全体像がつかみにくいですが、下記のイメージです。

例)車を作りたい。
車の設計図(クラス)から実物(インスタンス)を作成する。

  • 種類 = スポーツカー
  • 色 = 赤
  • 速度 = 150km

それでoptionsとか設定するのか。ややこしい。
とりあえず要素が見えたときの処理はif (entry.isIntersecting){}に書けばいいんだね。
optionsはデフォルトでいいや。

.itemは複数あるので各要素それぞれに対して、ovserverを発火させる

Items という変数に格納されている要素のリストを取り出し、それぞれの要素について、画面内に表示されたときに上で設定したアニメーションを実行します。

Items.forEach((item) => {
  observer.observe(item);
});