DEMO
一昔前に、ページスクロールに連動してDOMをあれこれしたい場合、documentのスクロールイベントのコールバックで、対象となるDOMが範囲内に入っているか否かを判定する必要がありました。
なので、僕もかつてページのスクロール量を管理するカスタムフックを作って、その中で、対象となるDOMを監視する実装をしていました。
が。最近、交差オブザーバー API (Intersection Observer API) たるものを知りまして、ターゲットとなる要素がビューポートに交差しているか否かが簡単に判定できることに気づきました。
それが、一番上に記載しているDEMOです。
干支がビューポートと交差した際、サイズが2倍に変化するように実装しています。
JSFiddleでDEMOをつくってみて気づいたのですが、iframe自体がスクロールした際にも発火してますね。
交差オブザーバー APIを使わずにこれを実現しようとすると、なかなか骨が折れる気がします。
ソースコード
HTML
<ol> <li> <p>🐭</p> </li> <li> <p>🐮</p> </li> <li> <p>🐯</p> </li> <li> <p>🐰</p> </li> <li> <p>🐲</p> </li> <li> <p>🐍</p> </li> <li> <p>🐴</p> </li> <li> <p>🐏</p> </li> <li> <p>🐵</p> </li> <li> <p>🐔</p> </li> <li> <p>🐶</p> </li> <li> <p>🐗</p> </li> </ol>
JavaScript
const observer = new IntersectionObserver(updateEntry, { threshold: 1 // 対象全てが交差した際 }); [].slice.call(document.querySelectorAll('li')).forEach((elm) => { observer.observe(elm); }); function updateEntry(entries) { entries.forEach((entry) => { entry.target.dataset.isShow = entry.isIntersecting; // 交差しているか否かをカスタムデータ属性に代入 }); }
SCSS
body { font-size: 80px; } ol { display: flex; flex-direction: column; align-items: center; justify-content: center; margin: 80px auto; } li { p { transform: scale(1); transition: transform .4s ease-in-out; // トランジションをつける } + li { margin-top: 80px; } &[data-is-show='true'] { p { transform: scale(2); // data-is-showがtrueになった際にサイズを倍にする } } }
という感じです。
めちゃめちゃ簡単にページスクロールに連動したイベントが管理できて嬉しい限り。
ブラウザの対応状況をみても、基本的な機能は実践投入しても問題なさそうです。
対応状況に不安が残る場合は、一応polyfillも用意されているので、こちらを使えばより安心です。
注意事項
対象となるDOMとビューポートの交差にはtransformが考慮されます。
なので、対象となるDOM自身を変形させてしまうと思わぬ挙動になることがあるので注意が必要です。
こちらのDEMOは、対象となるDOM自身を拡大しているため、変形した際に交差したり交差しなかったりしてしまっています。