2

我在想没有 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 上进行了搜索,然后弹出了这个问题。然而,关于已接受问题的最后一条评论指出它已被弃用。

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

w3.org/TR/DOM-Level-3-Events/#event-type-DOMSubtreeModified说这个事件已被弃用,我们会用什么来代替?

有替代品吗?
PS 它只需要在 Chrome 上工作,因为它是一个 Chrome 扩展。

4

3 回答 3

3

由于性能问题,目前不推荐使用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. 是否有 JavaScript/jQuery DOM 更改监听器?
于 2014-07-04T08:25:59.400 回答
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' );
于 2012-03-06T17:58:35.013 回答
0

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

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

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

于 2012-03-06T18:11:15.017 回答