【问题标题】:DOMNodeInserted equivalent in IE?DOMNodeInserted 在 IE 中的等效项?
【发布时间】:2011-01-09 18:40:46
【问题描述】:

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

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

【问题讨论】:

    标签: javascript internet-explorer dom mutation-events


    【解决方案1】:

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

    2014 年 2 月 6 日更新

    正如 cmets 中所指出的,有一种解决方法。它基于精心设计的 hack,我建议尽可能使用突变观察者。 详见@naugtur 的回答。 @naugtur 的答案已被删除,但可以在 https://github.com/naugtur/insertionQuery 找到解决方案

    【讨论】:

    • 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);
    • @Sean:好的,我不清楚。我的意思是propertychange不会触发innerHTML,当元素的内容以任何方式更改时,除了直接设置其innerHTML属性,这使得它作为DOMNodeInserted的解决方法几乎毫无用处:@ 987654322@。我已经更新了我的答案。
    • 看我的回答。可以模拟这个事件并且已经完成,尽管这可能比它值得付出更多的努力。
    • @Sean:我看到了。重写所有可能改变 DOM 的 DOM 方法和属性是不可能的,因此作为一般解决方案,这不是首发。
    【解决方案2】:

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

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

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

    【讨论】:

    • 只是好奇,你在哪里看到关于 DOMNodeInserted 的弃用部分?
    • @Anurag 注意:MutationEvent 接口是在 DOM 2 级事件中引入的,但尚未在用户代理之间完全且可互操作地实现。此外,也有人批评该接口在设计时引入了性能和实现方面的挑战。一个新的规范正在开发中,旨在解决突变事件解决的用例,但以更高效的方式。因此,本规范描述了突变事件的完整性,但不推荐同时使用 MutationEvent 接口和 MutationNameEvent 接口。
    • 知道新规范可能是什么,或者它在哪里实施?
    • "使用 onpropetrychange 监控 innerHTML。" - 我不明白。如果更改了 innerHTML,onproperychange 将不会触发 (msdn.microsoft.com/en-us/library/ms536956(v=vs.85).aspx)
    • @ripper234:从您引用的页面:“更改 child 元素的 innerText 或 innerHTML 不会导致 parent触发 onpropertychange 事件> 元素。"
    【解决方案3】:

    onreadystatechange 将在 IE 中工作。必须通过 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 event reference

    【讨论】:

      【解决方案4】:

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

      【讨论】:

        【解决方案5】:

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

        【讨论】:

          【解决方案6】:

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

          【讨论】:

          • 你能详细说明一下吗?
          • 你没有说太多。如果您有解决方案,请在此处提供。这里没有虚假陈述的地方。
          猜你喜欢
          • 2013-11-21
          • 2018-03-25
          • 2018-02-14
          • 2016-05-06
          • 1970-01-01
          • 1970-01-01
          • 2014-12-24
          • 2016-04-17
          • 2011-03-24
          相关资源
          最近更新 更多