generated at
scroll handlerを捨てよ、Intersection Observerへ出よう
この資料はWe Are JavaScripters! @26thLT資料です。

自己紹介
yamanoku @ yamanoku
おおやまみちのく a.k.a やまのく
既婚で1児の父と猫🐈🐈🐈の飼い主
神田大手町の間にある受託開発がメインの制作会社
マークアップ・フロントエンドエンジニア
技術書典#5にてサークル参加していました
Webアクセシビリティに関する本
WeJS登壇自体は初です
今月3回目の登壇です
人様の前での登壇は人生で3回目です

scroll handler 実装例
jQueryのonイベントで制御していた時代
scroll.js
$(function(){ $(window).on('scroll', function(){ // some event }); });

スクロール制御でつらいこと
スクロールイベントの発生は断続的なのでブラウザでの負荷がかかる
setTimeout でゴニョゴニョする
レスポンシブ時で要素のスクロール位置がレイアウトによって変化する場合
レスポンシブで高さが変わる・SPだとレイアウトが縦長になる
1回のみの動作させるときは flag 処理が必須
lazyloadなどの遅延読み込みをプラグインを使わずネイティブで分かりやすく出来ないか

日本語訳すると交点監視
特定のDOMが画面に出現したことをフックにする
要素の出現によるものなので位置や高さの変動などを気にしなくてよい
出現したとき、つまり断続的なイベントとならないのでパフォーマンスも良い
監視自体を任意のタイミングでやめることもできるので flag 処理も不要
Google公式でも推奨されている
SEOに適したLazyload例
SafariIE11が未対応なのでpolyfillが必要
https://polyfill.io/v2/polyfill.min.js?features=IntersectionObserver

コードサンプル
io.js
(() => { const clientHeight = document.documentElement.clientHeight; // ブラウザ表示領域 const target = document.querySelector('.hoge'); // 監視対象の要素 const header = document.querySelector('.header'); const observer = new IntersectionObserver((changes) => { // Intersection Observerの設定 for (const change of changes) { const rect = change.target.getBoundingClientRect(); const h = (0 < rect.top && rect.top < clientHeight) // 対象の上端は表示領域に入っている || (0 < rect.bottom && rect.bottom < clientHeight) // 対象の下端は表示領域に入っている || (0 > rect.top && rect.bottom > clientHeight); // 間が表示されている if(h) { // 対象が表示されていないとき header.classList.remove('scrolled'); // scorlledクラスを削除 } else { // 対象が表示されているとき header.classList.add('scrolled'); // scorlledクラスを付与 } } }); observer.observe(target); // 監視開始 })();

特定のタイミングでヘッダー要素を変更するとき
あるセクションに来たらタイトルを取得してパンくずの切り替えするみたいな要望
ページTOPボタンなどがフッターに到着した時に
position: fixed => position: absolue に変更
カチッと止まるような演出
フッターが画面にあらわれた瞬間に発火
position: sticky でもいいんだろうけどJavaScript会なので yamanoku
横スクロールもいけるんだろうか?
いけた yamanoku

ほかにもObserverはある

Resize Observer
リサイズイベントを監視
resize event window のみの発火
対象はDOM単位でも動くので textarea とかでも動く
window.matchMedia メソッドよりも汎用性ありそう
応用例(テキストチャット)
テキストチャットの大枠に overflow: scroll をつけて
Resize Observerでテキストチャットの中を監視して
親の scrollHeight clientHeight の差分からスクロールを下部に移動
Intersection Observerと同様polyfillが必要

DOMの変更を監視
動的に追加されたのも監視できる
オプションいろいろ
childList :対象ノードの子ノードの追加・削除を監視
attributes :対象ノードの属性の変更を監視
characterData :テキストノードの変更を監視
subtree :対象ノードと子孫ノードを監視
attributeOldValue :対象ノードの属性の変更前の値を取得できるようにする
characterDataOldValue :対象テキストノードの変更前の値を取得できるようにする
attributeFilter :指定した属性のみ監視対象とする
ほとんどのブラウザで使用可能

Obeserver API 関連リンク
Jxckさんブログ
yamanoku 次世代 Web カンファレンス 2019受かったのでいてきます
yamanoku どうでもいいんですが「Intersection Observer」でググると自分のQiita記事が上位に…(2018/11/20現在)

Let's Observer Life!