Intersection Observerを使って画像をフワッと表示させる方法



スクロールのイベントを検知してアニメーションを発火させる方法は色々ありますが、その中でも Intersection Observer を使う方法が便利だったので、使い方を書き残しておきます。




*参考



*Intersection Observer とは

JavaScript の API のひとつで、要素の交差を監視して、対象となる要素が監視要素と重なったときにイベントを実行することができます。使われる場面としては、ページをスクロールしたときの遅延読み込みや、無限スクロールなどがあります。


*使い方

基本的な流れとしては、IntersectionObserverオブジェクトを生成しobserve()で監視対象となる要素を指定するだけです。
IntersectionObserverオブジェクトの生成時には、実行したい処理となるコールバック関数と、そのコールバック関数を呼び出す際のオプションを設定します。
// コールバック関数のオプション
const options = {
  root: null,
  rootMargin: '5px',
  threshold: 0.5
}

// オブジェクト生成
const obs = new IntersectionObserver(showIntersect, options)

// 監視要素を指定
const imgs = document.querySelectorAll('.image')
imgs.forEach(img => obs.observe(img))

// 交差が閾値を超えたらクラスを付与する関数
function showIntersect(changes) {
 changes.forEach(change => {
   if (change.isIntersecting) {
     change.target.classList.add('show');
    }
  })
}

オプションには下記を設定することができます。
  • root
    交差を監視する要素を指定することができます。nullにすると画面との交差を監視します。
  • rootMargin
    root 要素のマージンを指定します。10pxを指定すると、要素が見える10px前から交差を検知することができます。デフォルトは0で負の値も指定可能です。
  • threshold
    コールバック関数を呼び出したい交差割合を指定します。0.5を指定すると、スクロールして要素が 50% 見え始めたらコールバック関数を実行します。

コールバック関数のなかで使っているisIntersectingは、要素が見えているか(閾値を超えたか)を判別することができます。他にはintersectionRatioを使って交差の割合で判別することもできます。

今回は次の画像が見え始めたら、showクラスを付与して画像をふわっと表示させるようにしました。ふわっと表示させるには、CSSでtransitionopacityを使っています。
<HTML>
<div class="content">
  <img class="image" src="https://www.pakutaso.com/shared/img/thumb/TSURU170308-057_TP_V.jpg" alt="サンプル">
  <img class="image" src="https://www.pakutaso.com/shared/img/thumb/TSURU170308-049_TP_V.jpg" alt="サンプル">
  <img class="image" src="https://www.pakutaso.com/shared/img/thumb/TSURU170308-054_TP_V.jpg" alt="サンプル">
  <img class="image" src="https://www.pakutaso.com/shared/img/thumb/TSURU170308-050_TP_V.jpg" alt="サンプル">
  <img class="image" src="https://www.pakutaso.com/shared/img/thumb/TSURU170308-051_TP_V.jpg" alt="サンプル">
  <img class="image" src="https://www.pakutaso.com/shared/img/thumb/TSURU170308-046_TP_V.jpg" alt="サンプル">
</div>

<CSS>
.content {
  height: 1000px;
}

.image {
  width: 350px;
  display: block;
  opacity: 0;
  margin-bottom: 250px;  
  
  &.show {
    opacity: 1;
    transition: opacity 0.5s ease-in;
  }
}


*所感

今回は画像をふわっと表示させただけですが、画像の遅延読み込みをすることでパフォーマンスを改善することもできます。
スクロールの量を意識する必要がなく簡潔に記述することができるので、アニメーションで動きを付けたいときなどに便利そうです。


Previous
Next Post »

人気の投稿