【问题标题】:Implementation of a DOM listenerDOM 监听器的实现
【发布时间】:2012-03-24 05:50:01
【问题描述】:

我以为没有 DOM 侦听器,所以我实现了自己的“重型”侦听器:

function CvHelper(stackApi) {
  var that = this;

  // check if room is finished loading
  this.init = function() {
    if ($('#loading').length) {
      setTimeout(that.init, 1000);
    } else {
      console.log('Chatroom finished loading');

      that.postListener();
    }
  }
}

(function() {
  var stackApi = new StackApi();
  var cvHelper = new CvHelper(stackApi);
  cvHelper.init();
})();

我认为这很糟糕。所以我在 SO 上搜索了这里并弹出了this question。但是last comment on the accepted question 声明它已被弃用。

$("#someDiv").bind("DOMSubtreeModified", function() {
  alert("tree changed");
});

w3.org/TR/DOM-Level-3-Events/#event-type-DOMSubtreeModified 表示此事件已被弃用,我们将使用什么来代替?

有替代品吗?
附言它只需要在 Chrome 上运行,因为它是一个 Chrome 扩展程序。

【问题讨论】:

    标签: javascript dom google-chrome-extension event-listener dom3


    【解决方案1】:

    Mutation Event 目前已被弃用,因为它存在性能问题。因此,请使用Mutation Observer。我在我的一个项目中使用 Mutation Observer 做了 DOM 更改侦听器,效果很好!为了您的进一步实施,这些链接将帮助您:

    1. http://gabrieleromanato.name/jquery-detecting-new-elements-with-the-mutationobserver-object/
    2. https://github.com/kapetan/jquery-observe
    3. Is there a JavaScript/jQuery DOM change listener?

    【讨论】:

      【解决方案2】:

      如果你看看:

      http://www.w3.org/TR/DOM-Level-2-Events/events.html#Events-MutationEvent

      它指出,关于 DOMSubtreeModified,“它可能会在对文档进行一次修改后触发,或者根据实现的判断,在发生多次更改后触发。”

      因此,如果您使用不同的 MutationEvent,例如 DOMNodeInserted,您可能会获得更具确定性的事件触发(在特定情况下,您只需向节点添加一个元素)。

      见下文:

      $('body').prepend( $('<div id="cow">Hello</div>') );
      
      $('#cow').bind("DOMNodeInserted",function(){ alert('hi'); } );
      
      $('#cow').prepend( $("<div></div>") );
      

      顺便说一句,这是在 Chrome 中测试的。

      希望对您有所帮助...

      更新: 或者,您可以在一个函数调用中添加多个事件类型。例如,为 DOMNodeInserted、DOMNodeRemoved、DOMAttrModified、DOMCharacterDataModified 添加四个事件处理程序,然后所有处理程序调用一个处理程序。

      更新:我写了一个小脚本来完成我在上一次更新中写的内容:

      $('body').prepend( $('<div id="cow">Hello</div>') );
      
      /**
      * This function registers event handlers which invoke the mutateHandler 
      * handler when any of the MutationEvents are fired on a node: DOMNodeInserted, 
      * DOMNodeRemoved, DOMAttrModified, DOMCharacterDataModified.
      *
      */
      var onMutate = function( mutateHandler ){
      
          var that = this;
          $(this).bind( "DOMNodeInserted", function( event ){ 
              mutateHandler.call( that, event ); 
          });
          $(this).bind( "DOMNodeRemoved", function( event ){ 
              mutateHandler.call( that, event ); 
          });
          $(this).bind( "DOMAttrModified", function( event ){ 
              mutateHandler.call( that, event );
          });
          $(this).bind( "DOMCharacterDataModified", function( event ){ 
              mutateHandler.call( that, event );
          });
      
      };
      
      onMutate.call( $('#cow')[0], function(){
          alert( $(this).attr('id') );
      });
      
      
      $('#cow').prepend( $("<div></div>") );
      $('#cow').addClass( 'my_class' );
      

      【讨论】:

      • “在特定情况下,您只需要向节点添加一个元素”是什么意思?
      • 我的意思是该事件只有在将元素添加到该节点时才会触发,例如示例代码的第三行。第三行是导致事件触发的原因。然而,更改属性不会导致事件触发。
      • 太好了,我会试一试的。我不关心chaing属性。它向我正在监听的 DOM 添加了元素。
      • 我已经创建了上面提到的方法。
      【解决方案3】:

      看起来它实际上只在DOM Level 3 Events的工作草案中被弃用,它提供了这个注释:

      警告! MutationEvent 接口是在 DOM Level 2 中引入的 事件,但尚未完全且可互操作地实施 跨用户代理。此外,也有人批评说 按照设计,接口引入了性能和实现 挑战。一个新的规范正在开发中,目的是 解决突变事件解决的用例,但在更多 高性能的方式。因此,本规范描述了突变事件 用于参考和遗留行为的完整性,但不推荐使用 使用 MutationEvent 接口和 MutationNameEvent 界面。

      所以,如果我理解正确,那么“还有替代品吗?”这个问题的答案。是“不,还没有。”

      【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2011-08-21
      • 2015-10-07
      • 2011-02-02
      • 1970-01-01
      • 1970-01-01
      • 2020-10-10
      • 2011-09-03
      相关资源
      最近更新 更多