IE中的DOMNodeInserted等效方法是什么?

19

除了使用定时器随时间计数元素并查看更改之外,我想不出更好的模拟此事件的方法。

是否有某种专有 IE 版本的 DOMNodeInserted?谢谢。

6个回答

7
没有,最接近的是propertychange事件,它会在元素属性或CSS属性发生变化时触发。它会在直接更改元素的innerHTML属性时触发,但不会在通过其他方式更改元素内容时触发(例如使用DOM方法如appendChild()或更改子元素的innerHTML)。
更新于2014年2月6日:正如评论中指出的,有一个解决方法。它基于一个复杂的hack,我建议尽可能使用变异观察器。请参阅@naugtur的答案以了解详细信息。@naugtur的答案已被删除,但解决方案可以在https://github.com/naugtur/insertionQuery找到。

有一个IE10+的解决方案:https://dev59.com/tXI95IYBdhLWcg3wzhV9#21600446 - naugtur
@naugtur:谢谢。我几周前确实读过这个。这种方法很聪明,但显然是一种明显的黑客技巧。我不喜欢它,但我想这总比什么都没有好。 - Tim Down
@TimDown 这更像是一个创意的想法,而不是一个hack。它基于早期实现的规范功能,有其优点(免费的CSS选择器)和缺点(事件触发延迟高达40毫秒),但它比JSONP少得多的hack,并且看看采用情况 ;) - naugtur
@naugtur:我也不喜欢JSONP :) - Tim Down
@Brad:Naugtur的回答已被删除,但我仍然可以看到它。解决方案可在https://github.com/naugtur/insertionQuery找到。 - Tim Down
显示剩余6条评论

6

你可以覆盖所有DOM操作方法-appendChild、insertBefore、replaceChild、insertAdjacentHTML等,并使用onpropertychange监视innerHTML。

你可能能够想出一个满足你要求的解决方案。

顺便说一下,似乎DOMNodeInserted等方法将被浏览器弃用。详情请参见http://www.w3.org/TR/DOM-Level-3-Events/#events-mutationevents


只是好奇,你在哪里看到关于DOMNodeInserted被弃用的部分? - Anurag
3
注:MutationEvent接口是在DOM Level 2 Events中引入的,但尚未在用户代理之间完全且可互操作地实现。此外,有人批评该接口设计引入了性能和实现方面的挑战。正在制定一项新规范,旨在以更高效的方式解决变异事件解决的用例。因此,本规范描述了变异事件的完整性,但弃用了MutationEvent接口和MutationNameEvent接口的使用。 - PetersenDidIt
2
你有任何想法,新规范是什么,或者它在哪里实现了吗? - Kragen Javier Sitaker
使用onpropertychange监控innerHTML属性。- 我不理解。如果更改innerHTML,onpropertychange将不会触发(http://msdn.microsoft.com/en-us/library/ms536956(v=vs.85).aspx) - ripper234
从您引用的页面中可以得知:"更改子元素的innerText或innerHTML不会导致父元素的onpropertychange事件触发。" - Sean Hogan

3

在IE中能够使用onreadystatechange。必须通过htc将DHTML行为附加到元素上,但htc文件不一定需要存在:

if (!!document.addEventListener)
  {
  $(domnode).get(0).addEventListener("DOMNodeInserted", fixtext, false);
  }
else
  {
  $(domnode).get(0).addBehavior("foo.htc");
  $(domnode).get(0).attachEvent("onreadystatechange", fixtext);
  }

onreadystatechange 事件参考


1
一个不太优雅的解决方案是拦截 Element 类型的原型方法,如下所示:
window.attachEvent('onload', function() {
    invokeNodeInserted(document);
    (function(replace) {
        Element.prototype.appendChild = function(newElement, element) {
            invokeNodeInserted(newElement);
            return replace.apply(this, [newElement, element]);
        };
    })(Element.prototype.appendChild);
    (function(replace) {
        Element.prototype.insertBefore = function(newElement, element) {
            invokeNodeInserted(newElement);
            return replace.apply(this, [newElement, element]);
        };
    })(Element.prototype.insertBefore);
    (function(replace) {
        Element.prototype.replaceChild = function(newElement, element) {
            invokeNodeInserted(newElement);
            return replace.apply(this, [newElement, element]);
        };
    })(Element.prototype.replaceChild);
});

0

使用Paul Sweatte建议的onreadystatechange并不真正起作用。 readystatechange事件仅在加载foo.htc时触发。 它与更改DOM节点无关。

我设置了一个小小的小样来演示它。 看看http://jsfiddle.net/Kermit_the_frog/FGTDv/http://jsfiddle.net/Kermit_the_frog/FGTDv/embedded/result/

HTML:

<input type="button" id="fooBtn" value="add" />
<div id="fooDiv"></div>

JS/Jquery:

function bar(e) {
    var state = $('#fooDiv').get(0).readyState;
    alert (state);
}

$("#fooBtn").on("click", function(){
    $('#fooDiv').get(0).addBehavior("foo.htc");
    $('#fooDiv').get(0).attachEvent("onreadystatechange", bar);
});

正如您所看到的:即使没有进行DOM操作,也会触发readystatechange事件。


-2

看起来,在IE中可以使用DHTML Behaviors来模拟DOMNodeInserted


6
你能详细说明一下吗? - naugtur
你没有说太多。如果你有解决方案,请在这里提供。这里不容许虚假陈述。 - Slavik Meltser

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接