DOMNodeInserted 在 IE 中等效吗?

IT技术 javascript internet-explorer dom mutation-events
2021-01-30 10:01:54

除了使用计时器来计算一段时间内的元素数量并寻找变化之外,我想不出更好的方法来模拟这个事件。

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

6个回答

不,没有。最接近的是propertychange事件,它响应元素的属性或 CSS 属性的更改而触发。它在响应直接更改innerHTML元素属性时触发,但不会在元素的内容通过其他方式(例如,通过使用 DOM 方法,例如appendChild()或通过更改innerHTML子元素的 )更改时触发

2014 年 2 月 6 日更新

正如评论中所指出的,有一个解决方法。它基于精心设计的 hack,我建议尽可能使用变异观察器。有关详细信息,请参阅@naugtur 的回答@naugtur 的回答已被删除,但可以在https://github.com/naugtur/insertionQuery找到解决方案

@肖恩:我看到了。覆盖所有可能更改 DOM 的 DOM 方法和属性是不可能的,因此作为通用解决方案,这是一个非入门者。
2021-03-14 10:01:54
@Sean:好的,我不清楚。我的意思是当元素的内容通过直接设置其属性以外的任何方式更改时propertychange不会触发,这使得它作为以下解决方法几乎无用jsfiddle.net/eze5V/8我已经更新了我的答案。innerHTMLinnerHTMLDOMNodeInserted
2021-03-26 10:01:54
2021-04-02 10:01:54
javascript:var div = document.createElement("div"); div.onpropertychange = function() { var e = window.event; alert(e.propertyName + ":" + this[e.propertyName]); }; document.body.appendChild(div); div.innerHTML = "你好"; 无效(0);
2021-04-03 10:01:54
看我的回答。可以模拟这个事件并且已经完成,尽管它可能比它值得付出更多的努力。
2021-04-08 10:01:54

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

您或许能够提出满足您要求的解决方案。

顺便说一句,DOMNodeInserted 等似乎将来会被浏览器弃用。http://www.w3.org/TR/DOM-Level-3-Events/#events-mutationevents

知道新规范可能是什么,或者它在哪里实现?
2021-03-21 10:01:54
@ripper234:来自您引用的页面:“更改元素的innerText 或innerHTML不会导致为父元素触发onpropertychange 事件。”
2021-03-21 10:01:54
@Anurag 注意:MutationEvent 接口是在 DOM Level 2 Events 中引入的,但尚未在用户代理之间完全且互操作地实现。此外,也有人批评界面的设计带来了性能和实现方面的挑战。一个新的规范正在开发中,旨在解决突变事件解决的用例,但以更高效的方式。因此,本规范为了完整起见描述了突变事件,但不赞成使用 MutationEvent 接口和 MutationNameEvent 接口。
2021-03-22 10:01:54
“使用 onpropetrychange 监控 innerHTML。” - 我不明白。如果更改了 innerHTML ( msdn.microsoft.com/en-us/library/ms536956(v=vs.85).aspx ),则不会触发 onproperychange
2021-04-08 10:01:54
只是好奇,你在哪里看到关于 DOMNodeInserted 的弃用部分?
2021-04-09 10:01:54

onreadystatechange 将在 IE 中工作。DHTML 行为必须通过 htc 附加到元素,但 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 事件参考

一个肮脏的解决方法是拦截 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);
});

按照 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 事件。