宇賀みなさんこんにちは、UI開発者の宇賀です。何か変更があったら聞きに行かなくても教えて欲しい...。JavaScriptを書いていると、そんな風に思うことが多々あると思います。以前はオブジェクトのプロパティの変更を検出したり、要素が出力されたのを検出したりすることはなかなか難しかったり、コストがかかるものでした。)がJavaScriptの仕様(正確にはDOMの仕様やECMAScriptの仕様など)には用意されています。今回はそんなオブザーバーの仲間をいくつか「仕様書へのリンク、大まかなできること、サンプル」の順に紹介したいと思います。この記事に登場するサンプルはブラウザによって正しく動作しない可能性があります。64以降のバージョンでの動作を確認しています。対象の要素の子孫ノードも監視対象に含める開発者ツールでコンソールを見ながら「MutationObserverの動作サンプル」内にある要素の属性を操作したり、子要素を挿入、削除したりしてみてください。'hogehoge';})();要素に何かしら変更があったことを知ることができます。変更が検出されると、次の内容がコールバック関数の引数に渡されます。変化前の値MutationObserverは要素の状況が開発者(自分)のコントロール下にないような状況においても、非常に有効なAPIです。「非同期的に情報が自動更新されるWebツールを業務などで使っており、更新を認識して必要な情報があればプッシュ通知させることでより効率的に作業をすすめられるようなブラウザ拡張を開発する場合」や、「サードパーティのウィジェットを読み込まれたタイミングでなにがしかの処理を実行しなければならず、しかしそのウィジェットの読み込みが終わるタイミング、DOMツリーに挿入されるタイミングが不明」のような状況下で力を発揮してくれます。コンテンツエリアの高さ開発者ツールからCSSを操作したりウィンドウの幅をリサイズしたりして、「ResizeObserverの動作サンプル」内にある要素の横幅を変化させてみてください。observer.observe(body.children[2]);})();JavaScriptをスタイリングに利用することを余儀なくされる状況では、windowオブジェクトのresizeイベントにハンドラを登録して画面サイズの変更を検知し、リサイズを想定している全ての要素のスタイルを調整しなおす、といった実装が多いのではないでしょうか。ResizeObserverを利用することで、要素単位でサイズの変化を検出し、要素単位でレイアウトの調整を行うことができるようになります。本記事執筆時点ではまだまだWebサイト上では使える段階にないですが、ResizeObserverが使える環境になれば、JavaScriptによるスタイリングのパフォーマンスが向上するかもしれないですね。EdgeなどのPCブラウザで動作します)まだ見えてない「対象の要素」が画面内に入ったときに「まだ見えてない」が「見えた!」に変化するサンプルです。EdgeなどのPCブラウザで動作します)JavaScriptが有効の場合、要素がふわっと表示されます。このインスタンスに関連づいている監視を全て終了})();これまでwindowのscrollイベントに、要素が画面内に存在するかどうかを判定するハンドラを登録する方法で実装することが多かった印象ですが、IntersectionObserverを使うことでより手軽に「IntersectionObserverの動作サンプル2」のような実装が可能になりました。手軽さだけでなく1pxでもスクロールすればハンドラが呼ばれてしまうscrollイベントに、要素の座標位置関係を計算させるハンドラを登録するよりも負荷がかかりにくく、パフォーマンス面でも改善が望めます。サンプルコードにもあるように、IntersectionObserverオブジェクトからインスタンスを生成する際に渡すオプション(第2引数)で、ルートとする要素や交差判定を行う領域の制御、コールバック関数を呼び出すタイミングの交差量を設定できます。まとめ今回ご紹介したObserverは次の3種類です。MutationObserverResizeObserverIntersectionObserver要素の変化を監視できたり、要素のリサイズを監視できたり、要素の交差を監視できたり...。このようなObserver系オブジェクトは他にも存在します。昔は苦労していたことも、各種Observerを利用することでいろいろと解決しやすくなってきている印象です。