「知らなかったからさ」
確かに最近のWeb APIの進歩は目を見張るものがあります。半年もほっておくと、見たことも聞いたこともないAPIが、既に実用レベルとなっていることもあります。
しかし、このコンテンツで紹介しようとしているAPIは、何とあのInternet Explorer 11でさえサポートしています。
何年ほっておいたのでしょうか。
MutationObserverという、DOMの変化を監視するAPIのご紹介です。
最近のJavascriptは非同期のAPIが多くなったために、複数の非同期APIが関わる複雑な処理を実装することも多くなりました。
この様な処理では、最終的に終了したタイミングを知ることが難しいことがあります。
しかし、その複雑な処理が、最終的にどこかの要素に処理結果を設定するのであれば、その要素を監視すれば処理の終了を知ることができます。
下記の例では、複雑な処理の代わりにタイマで処理結果を設定させています。
処理結果が設定された時点で、その旨を「結果表示 =>」の後に表示します。
監視の対象は、IDがsample_text_target
の要素です。4行目で初期化し、18行目で監視を開始しています。
監視の開始で第2引数として渡しているconfig
が、監視する内容です。
ここで指定しているchildList
は、テキストノードも含む子ノードの変更を監視させる指示です。
childList
は、直接の子ノードのみを監視するので、孫ノードなどの変更は監視しません。子孫ノードを全て監視する場合は、subtree
を指定します。
コールバック関数の中で、disconnect()
を呼び監視を終了しています。監視を始めると、わずかですがマシンの負荷が上がるので、内部的には永久ループによる処理を行っているものと思われます。
ページをloadした時点で監視を開始して、unloadまで続けるといった使い方よりは、都度都度で監視を開始/終了するような使い方のほうが合っている気がします。
一つだけであれば問題となるほどの負荷ではありませんが、複数の監視を同時に実行すると、その分負荷が高まります。
結果表示 =>
要素のサイズ変更のタイミングを知りたいことはよくあるのですが、通常の要素はresizeイベントを発火しないので、いろいろなハックが出回っています。
MutationObserverを使えば、簡単に知ることができます。但し、その要素のインラインスタイルを変更した場合に限られます。
下記例では、7行目でstyle
属性の内容を変更して、横幅を変えています。
インラインスタイルの変更を監視するためには、attributes
を指定します。
この例では、コールバック関数は変更のタイミングを知るためだけに使用しています。
監視対象のどの属性が変更となっても呼び出されるので、想定のものが変更されたかをチェックしています。
結果表示 =>
attributes
を使って監視できるのは、あくまでもDOM上の属性が変更されたかどうかなので、その要素のJavascript上のプロパティ()
これは、サイズの監視とほぼ同じです。
結果表示 =>
className
やtitle
といった、直接DOMの属性が変更されるものは監視の対象ですが、イベントハンドラなどの設定は対象外のようです。
次の例のように、イベントハンドラを設定しても、検知されません。但し、設定後はマウスでクリックすると、ダイアログは表示されます。
コードにバグがないことを祈るばかりです...
結果表示 =>