まだ存在しないDOMノードの突然変異を観察することは可能ですか?
例:
私のアプリはある時点でdivを作成します:<div id="message" data-message-content="foo" data-message-type="bar" />
。
このdivの作成と変更を監視したい。
var mutationObserver = new MutationObserver(function(mutations){
// Some code to handle the mutation.
});
mutationObserver.observe(
document.querySelector('#message'),
{
attributes: true,
subtree: true,
childList: true,
characterData: false
}
);
);
現在、これはerrorを返します。これは、#message
がnullであるためです(divはまだ作成されていません)。
Failed to execute 'observe' on 'MutationObserver': parameter 1 is not of type 'Node'.
明白な解決策は、body
を監視し、ミューテーションのいずれかがdiv#Message
の作成であるかどうかを確認することですが、これは悪いアイデアのようです/おそらくパフォーマンスが悪いようです。
監視できるのは既存のノードのみです。
ただし、心配しないでください。getElementByIdは、すべてのミューテーションの追加ノードの列挙に比べて非常に高速であるため、Devtools-> Profilerパネルに表示されるように、要素が表示されるのを待つことはまったく負担になりません。
_function waitForAddedNode(params) {
new MutationObserver(function(mutations) {
var el = document.getElementById(params.id);
if (el) {
this.disconnect();
params.done(el);
}
}).observe(params.parent || document, {
subtree: !!params.recursive,
childList: true,
});
}
_
使用法:
_waitForAddedNode({
id: 'message',
parent: document.querySelector('.container'),
recursive: false,
done: function(el) {
console.log(el);
}
});
_
常にdevtoolsプロファイラーを使用し、オブザーバーコールバックがCPU時間の1%未満を消費するようにしてください。
subtree: false
_)for (var i=0 ....)
ループに比べて負荷が高く、MutationObserverコールバックは1秒あたり100回起動する可能性があるためです。複雑な最新のページでは、突然変異の各バッチに数十、数百、数千のaddedNodes
があります。for
ループと同じ速さで実行されない限り、MutationObserverコールバック内で 遅いES2015ループfor (v of something)
のように使用しないでください。