スクロールして要素が画面内に入るとアニメーションさせる仕組み
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をすぐ作成して観測を開始するので、何回も動かしたくない場合は、これが簡単かもしれない。