Implementation of a DOM listener

2019-05-19 23:47发布

I was thinking there was no DOM listener so I implemented my own 'heavy' listener:

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();
})();

I think this just sucks. So I did a search on here on SO and this question popped up. However the last comment on the accepted question states that it is deprecated.

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

w3.org/TR/DOM-Level-3-Events/#event-type-DOMSubtreeModified says this event is deprecated, what would we use instead?

Is there a substition for it?
P.S. It only has to work on Chrome, because it is an Chrome extension.

3条回答
Emotional °昔
2楼-- · 2019-05-20 00:35

If you take a look at:

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

It states that, regarding DOMSubtreeModified, "It may be fired after a single modification to the document or, at the implementation's discretion, after multiple changes have occurred."

Therefore, if you use a different MutationEvent, say DOMNodeInserted, you may get a more deterministic firing of events (You'd just have to add an element to the node in that specific case).

See below:

$('body').prepend( $('<div id="cow">Hello</div>') );

$('#cow').bind("DOMNodeInserted",function(){ alert('hi'); } );

$('#cow').prepend( $("<div></div>") );

This was tested in Chrome, btw.

Hope that helps...

UPDATE: Alternatively, you could add more than one event type in one function call. For example, adding four event handlers for DOMNodeInserted, DOMNodeRemoved, DOMAttrModified, DOMCharacterDataModified, then all of the handlers call a single handler.

UPDATE: I wrote a little script that does what I had just written in the previous update:

$('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' );
查看更多
Explosion°爆炸
3楼-- · 2019-05-20 00:44

The Mutation Event is currently deprecated because of it's performance issue. Hence, Please use the Mutation Observer. I did the DOM changes listener in one of my project using Mutation Observer and it worked great! For your further implementation, these links will help you:

  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?
查看更多
爷、活的狠高调
4楼-- · 2019-05-20 00:53

It looks like it's actually only deprecated in in the working draft of DOM Level 3 Events, which provides this note:

Warning! The MutationEvent interface was introduced in DOM Level 2 Events, but has not yet been completely and interoperably implemented across user agents. In addition, there have been critiques that the interface, as designed, introduces a performance and implementation challenge. A new specification is under development with the aim of addressing the use cases that mutation events solves, but in more performant manner. Thus, this specification describes mutation events for reference and completeness of legacy behavior, but deprecates the use of both the MutationEvent interface and the MutationNameEvent interface.

So if I understand correctly, the answer to the question "Is there a substitution yet?" is "no, not yet."

查看更多
登录 后发表回答