スクロールして要素が画面内に入るとアニメーションさせる仕組み
2024.11.06
画面内に要素が表示されたらDOM操作してくれるやつ
背中が透けるほどにこすられまくった仕組みの実装で利用する。
あらかじめhtml側の動かしたい要素にclass=”inview”をつけておき、要素がviewport内に表示されたらclass=”inview is-inview”となる。
また要素がviewportから外れたらclass=”inview”となり、is-inviewがtoggleする簡単な仕組み。
これをscrollイベントで実行すると、スクロールが発生するたびに頻繁にトリガーされてしまいます。
しかしながらintersectionObserverを使うと非同期に処理を最適化してくれるため、リソースの節約に繋がります。
ソースコード確認
// ターゲット要素をすべて取得 const targets = document.querySelectorAll('.inview'); // IntersectionObserverを設定 const observer = new IntersectionObserver((entries) => { entries.forEach(entry => { if (entry.isIntersecting) { // ビューポート内に表示されたらクラスを追加 entry.target.classList.add('is-inview'); } else { // ビューポート外に出たらクラスを削除 entry.target.classList.remove('is-inview'); } }); }, { threshold: 0.1 // 要素が10%表示されたら反応 }); // 各ターゲット要素をオブザーバーに監視させる targets.forEach(target => observer.observe(target));
IntersectionObserver
指定した要素が画面に表示されたら~のような処理を行う場合、スクロールのたびに毎回実行されるscrollイベントではパフォーマンスが悪いので、非同期で監視してくれる。
MDN:IntersectionObserver
https://developer.mozilla.org/ja/docs/Web/API/IntersectionObserver
CSSの例
.inview { opacity: .5; transition: opacity .5s ease-in-out; &.is-inview { opacity: 1; } }
class=”inview”状態では半透明であったものが、class=”inview is-inview”となるときっちり見える仕組み。
このjsではis-inviewがtoggleするので、ease-in-outとしている。
toggleしなくてもいいよ。1回だけでいいよっていう場合
document.querySelectorAll('.inview').forEach(el => { new IntersectionObserver((entries, observer) => { entries.forEach(entry => { if (entry.isIntersecting) { entry.target.classList.add('is-inview'); observer.unobserve(entry.target); } }); }).observe(el); });
この場合、intersectionObserverをすぐ作成して観測を開始するので、何回も動かしたくない場合は、これが簡単かもしれない。