私は、さまざまなブラウザーでまだ準備が整っていない W3C undomanager に似た undomanager を構築しています。DOM への変更を監視しながらコールバックを呼び出す単純なトランザクション呼び出しを実装し、後で変更を元に戻す (またはやり直す) ために使用できる必要な構造を配列に追加します。
簡単な例:
function transact(callback){
/* Watch content area for mutations */
observer = new MutationObserver(function(){
/* TODO: collect mutations in here */
alert('Mutations observed');
});
observer.observe(document.getElementById('content'), {
attributes: false,
childList: true,
characterData: false,
subtree: false
});
/* Perform the callback */
callback();
/* Stop observing */
//observer.disconnect();
setTimeout(function(){ observer.disconnect();}, 1);
}
これを使用するには:
transact(function(){
var p = document.createElement('p');
p.innerHTML = 'Hello';
document.getElementById('content').appendChild(p);
});
observer.disconnect()
すぐに呼び出すと、ミューテーション オブザーバーはalert
呼び出しに到達しませんが、setTimeout を使用すると正常に動作します。
私は setTimeout 呼び出しに完全に満足しています。唯一の問題は、大きな変更の場合、切断を 800 ミリ秒も遅らせる必要があることです。
DOM の変更が実際に完了する前に切断が発生したかのように見えるため、何も検出されません。
これは、Firefox 25 と Chrome 32 の両方で発生します。
はローカル変数なので、すぐに範囲外になるのではないかと一瞬考えましたobserver
が、グローバル変数に変更しても効果はありませんでした。disconnect()
DOMに追いつく機会を与えるために、への呼び出しを遅らせる必要があるようです。
これはブラウザのバグですか?disconnect()
DOM が再び準備ができたらすぐに呼び出すより良い方法はありますか?