読者です 読者をやめる 読者になる 読者になる

DOMNodeRemovedFromDocumentが効いていない?

JavaScript

こんなコードを書いた。elemにはdocumentツリー内の適当な要素が代入されている。

elem.addEventListener('DOMNodeRemoved', function() { alert('removed.'); }, false);
elem.addEventListener('DOMNodeRemovedFromDocument', function() { alert('removedFromDocument.'); }, false);
elem.parentNode.removeChild(elem);

DOM3 Eventsの仕様通りの動作をするならば,「removed.」→「removedFromDocument.」という順番でメッセージが表示されるはずだが,「removed.」しか表示されない。

elem.addEventListener('DOMNodeRemoved', function() { alert('removed.'); }, false);
elem.addEventListener('DOMNodeRemovedFromDocument', function() { alert('removedFromDocument.'); }, false);
elem.parentNode.parentNode.removeChild(elem.parentNode);

こうすると,「removedFromDocument.」のみ表示されるはずなのだが,何も起きない。
Firefox 3がDOMNodeRemovedにだけ対応していて,DOMNodeRemovedFromDocumentには対応していないだけかと思ったのだが,そういうわけでもないっぽい?
うーん。

追記

同じコードをOperaSafariGoogle Chromeで実行してみたところ,Operaでは想定通りの動作,WebKit系2ブラウザではなぜか「Removed.」が2回表示された。これまたよく分からない結果だが,何も起きないよりはマシかも。

追記2

しょうがないからDOMNodeRemovedを使うことにした。

var p = elem;
while(p) {
    p.addEventListener('DOMNodeRemoved', fun, false);
    p = p.parentNode;
}

追記3

上記のコードは正しく動作しなかった。というか,funが親要素の数と同じ回数呼び出されてしまっていろいろ不都合だった。以下のコードで想定通りの動作をした。

document.documentElement.addEventListener('DOMNodeRemoved', function(e) {
    if(e.target.compareDocumentPosition(elem) & Node.DOCUMENT_POSITION_CONTAINED_BY)
        fun();
}, false);

DOMNodeRemovedイベントはバブリングするからドキュメントのルートで1回受け止めればそれで済むんですね。未だにイベント周りは分かってないことがいっぱいだなー。
DOMNodeRemovedFromDocumentの件も仕様を勘違いしてるだけかも…。