
スクロール判定の作成方法
一般的に特定の要素までスクロールしたらCSSのactiveクラスを付けてCSSアニメーションを実行する場合、JavaScriptのscrollイベントが使用されるが、scrollイベントを使用すると処理が重くなるという問題がある。
また、特定の要素すべてにactiveクラスを付けてCSSアニメーションを実行する要素がなくなってもscrollイベントを実行し続けているWebサイトが多く存在する。
IntersectionObserverを使用する
scrollイベントではなくIntersectionObserverを使用すると処理が軽くなる。
IntersectionObserverとはターゲットとなる要素を監視するためのAPIで詳細はMDNのWebサイトに書かれているが、内容が少し難しいので最初はターゲットとなる要素までスクロールされたか判定できるAPIだと認識できれば良いです。
IntersectionObserverを使用したコード
まずJavaScriptの前にHTMLとCSSを用意する。
以下のサンプルでは.scrollAnimeの要素までスクロールされた際に.activeが追加された場合はCSSアニメーションが動作するようにした。
<h1>IntersectionObserverによるスクロール位置取得</h1> <h2>↓ 1000px以上スクロールして確認してみてください。</h2> <div class="scrollAnime">scrollAnime1</div> <hr> <div class="scrollAnime">scrollAnime2</div>
h2, hr { margin-bottom: 1000px; } .scrollAnime { transition: all 1s linear; transform: translateX(-20px); opacity: 0; } .scrollAnime.active { transform: translateX(0); opacity: 1; }
JavaScriptは以下の通り。querySelectorAllでCSSアニメーションを動作させる要素を取得する。
すべての要素に.activeが追加された場合はobserver.disconnect()で終了されるため、scrollイベントだけの処理とは違いJavaScriptが動作しつづけることがない。
const targets = [].slice.call(document.querySelectorAll('.scrollAnime')) const targetsLen = targets.length if (targetsLen) { const observer = new IntersectionObserver(changes => { for (let i in changes) { if (changes[i].isIntersecting) { changes[i].target.classList.add('active') const activeLen = document.querySelectorAll('.scrollAnime.active').length if (targetsLen === activeLen) { observer.disconnect() } } } }) targets.forEach(target => observer.observe(target)) }
ちなみにIntersectionObserverはIE11は使用不可のため、IE11も対象のWebサイトの場合はpolyfill.min.jsを読み込んでください。
polyfill.min.jsを読み込めばIE11でも動作します。
<script src="https://polyfill.io/v2/polyfill.min.js?features=IntersectionObserver"></script>
IntersectionObserverによるスクロール判定CSSアニメーションサンプル