scroll handlerを捨てよ、Intersection Observerへ出よう
https://gyazo.com/8ac7309a1b4012f3592a7c8bc2e086eb
この資料はWe Are JavaScripters! @26thのLT資料です。
自己紹介
yamanoku.icon @ yamanoku
おおやまみちのく a.k.a やまのく
Twitter
GitHub
Qiita
既婚で1児の父と猫🐈🐈🐈の飼い主
株式会社GEEK.icon 株式会社GEEK
神田・大手町の間にある受託開発がメインの制作会社
マークアップ・フロントエンドエンジニア
https://www.geek.co.jp/
https://blog.geek.co.jp/
GitHub.icon https://github.com/geekcojp/
npm.icon https://www.npmjs.com/org/geekcojp
Qiita.icon https://qiita.com/organizations/geekinc
技術書典#5にてサークル参加していました
https://gyazo.com/68a19f11b771c82a7887ede7791af040
Webアクセシビリティに関する本
これからはじめるWebアクセシビリティ - こんのいぬ - BOOTH(同人誌通販・ダウンロード)
WeJS登壇自体は初です
今月3回目の登壇です
人様の前での登壇は人生で3回目です
scroll handler実装例
jQueryのonイベントで制御していた時代
code:scroll.js
$(function(){
$(window).on('scroll', function(){
// some event
});
});
スクロール制御でつらいこと
スクロールイベントの発生は断続的なのでブラウザでの負荷がかかる
setTimeoutでゴニョゴニョする
レスポンシブ時で要素のスクロール位置がレイアウトによって変化する場合
レスポンシブで高さが変わる・SPだとレイアウトが縦長になる
1回のみの動作させるときはflag処理が必須
lazyloadなどの遅延読み込みをプラグインを使わずネイティブで分かりやすく出来ないか
Intersection Observer
日本語訳すると交点監視
https://gyazo.com/d26fc64bbcc8fade2c51604932c8c698
特定のDOMが画面に出現したことをフックにする
要素の出現によるものなので位置や高さの変動などを気にしなくてよい
出現したとき、つまり断続的なイベントとならないのでパフォーマンスも良い
監視自体を任意のタイミングでやめることもできるのでflag処理も不要
Google公式でも推奨されている
SEOに適したLazyload例
https://gyazo.com/7abca63e0ea4c032c8af819d3b155391 https://developers.google.com/search/docs/guides/lazy-loading
SafariとIE11が未対応なのでpolyfillが必要
https://polyfill.io/v2/polyfill.min.js?features=IntersectionObserver
https://gyazo.com/2bd52198cc1e1ba91b6ae92269e98a39
コードサンプル
code: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); // 監視開始
})();
特定のタイミングでヘッダー要素を変更するとき
https://gyazo.com/da422ec4777c54eda3b060cd1009d18a
https://codepen.io/yamanoku/pen/KqLWZM
あるセクションに来たらタイトルを取得してパンくずの切り替えするみたいな要望
https://gyazo.com/37bcf956627c8848fd6e964291a36de7
https://codepen.io/yamanoku/pen/VVQGLP
ページTOPボタンなどがフッターに到着した時に
https://gyazo.com/c146e3d691b188020d680a76c2b37e87
https://www.geek.co.jp/recruit/engineer/
position: fixed => position: absolueに変更
カチッと止まるような演出
フッターが画面にあらわれた瞬間に発火
position: stickyでもいいんだろうけどJavaScript会なので yamanoku.icon
横スクロールもいけるんだろうか?
https://gyazo.com/4d24e017117aa54fb77f02a97299e44f
https://codepen.io/yamanoku/pen/VVQqdr
いけた yamanoku.icon
ほかにもObserverはある
Resize Observer
Mutation Observer
Resize Observer
リサイズイベントを監視
resize eventはwindowのみの発火
対象はDOM単位でも動くのでtextareaとかでも動く
https://gyazo.com/cacb53d8edf95f6de20107b697db0b78
https://codepen.io/yamanoku/pen/Jepmma
window.matchMediaメソッドよりも汎用性ありそう
応用例(テキストチャット)
https://gyazo.com/ec169d17613f94eb844715fe6774d5e5
https://rawgit.com/WICG/ResizeObserver/master/examples/chat.html
テキストチャットの大枠に overflow: scrollをつけて
Resize Observerでテキストチャットの中を監視して
親のscrollHeightとclientHeightの差分からスクロールを下部に移動
Intersection Observerと同様polyfillが必要
Mutation Observer
DOMの変更を監視
動的に追加されたのも監視できる
オプションいろいろ
childList:対象ノードの子ノードの追加・削除を監視
attributes:対象ノードの属性の変更を監視
characterData:テキストノードの変更を監視
subtree:対象ノードと子孫ノードを監視
attributeOldValue:対象ノードの属性の変更前の値を取得できるようにする
characterDataOldValue:対象テキストノードの変更前の値を取得できるようにする
attributeFilter:指定した属性のみ監視対象とする
ほとんどのブラウザで使用可能
https://gyazo.com/30beed0eb1626c4a085d4c6bc811c127 https://caniuse.com/#search=Mutation%20Observer
Obeserver API 関連リンク
Observerを使って要素を監視してみよう! | フロントエンドBlog | ミツエーリンクス
Jxckさんブログ
Intersection Observer を用いた要素出現検出の最適化 | blog.jxck.io
ResizeObserver による変更検知と Element Query | blog.jxck.io
yamanoku.icon 次世代 Web カンファレンス 2019受かったのでいてきます
DOMの変更を監視するにはMutationObserverを使う – おかかウェブ
Intersection Observer (日本語訳)
yamanoku.icon どうでもいいんですが「Intersection Observer」でググると自分のQiita記事が上位に…(2018/11/20現在)
https://gyazo.com/28ffa6d9b0847c4b151a9fe333a2f069
Let's Observer Life!
https://gyazo.com/7445b6198394060a4e49724fec2cb487