MutationObserverを使うと要素(DOM)のCSS等の属性変更を監視して、変更を検知したタイミングでコールバック関数を呼び出せます。
例えばヘッダーの高さがウィンドウの幅に応じて変化する場合に、メニューの位置をヘッダーの下端に合わせなければならない時などに重宝します。
実行サンプル
<div id="target_node">この要素がランダムに移動</div>
<div id="chase_node">この要素は上記要素を監視して変更を検知したら追従</div>
ソースコード
<div style="position:relative;width:100%;height:300px;"> <div id="target_node" style="position:absolute;width:210px;height:80px;background:#DFF;"> このノードがランダムに移動 </div> <div id="chase_node" style="position:absolute;width:210px;height:80px;background:#FFD;"> この要素は上記要素を監視して変更を検知したら追従 </div> </div> <script> var tid; window.addEventListener("load",function(){ //監視対象ノードに属性変更があった場合の処理 const observer = new MutationObserver(function(MutationRecords){ //変更内容は変数MutationRecordsに届く //console.log(MutationRecords); //#target_node に変更があるので #chase_node を追従させる let t = document.getElementById("target_node"); let c = document.getElementById("chase_node"); let r = t.getBoundingClientRect(); c.style.left=(parseInt(t.style.left)+20)+'px'; c.style.top=(parseInt(t.style.top)+r.height+10)+'px'; }); //#target_nodeの属性変更の監視を開始する observer.observe( document.getElementById("target_node"), //監視対象ノードを指定 { childList: true, //対象ノードの子ノード(テキストノード含む)の変更も監視する場合はtrue attributes: true, //対象ノードの属性変更を監視する場合はtrue characterData: true, //対象ノードのデータの変更を監視する場合はtrue subtree: true, //対象ノードの子孫ノードも監視対象に含める場合はtrue attributeOldValue: true, //変更前の属性値を記録(MutationRecords[].oldValue)する場合はtrue characterDataOldValue: false, //変更前のデータ(テキストノード)を記録(MutationRecords[].oldValue)する場合はtrue attributeFilter:['style'], //style属性(つまりCSS)の変更がないか監視 } ); //#target_nodeを2秒ごとにランダムな位置に移動させる tid=setInterval(function(){ let elm=document.getElementById("target_node"); let max=160; elm.style.left=Math.floor(Math.random() * max)+'px'; elm.style.top=Math.floor(Math.random() * max)+'px'; }, 2000); }); window.addEventListener("unload",function(){ //インターバルのクリア clearInterval(tid); //監視を中止 observer.disconnect(); }); </script>