Why Is the Domsubtreemodified Event Deprecated in Dom Level 3

Why is the DOMSubtreeModified event deprecated in DOM level 3?

If you scroll down a bit, you see:

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.

The replacement API is mutation observers, which are fully specified in the DOM Living Standard that supercedes all of the DOM level X silliness.

Detecting DOM change events

I think what you're looking for is DOMSubtreeModified

Edit: upon further inspection this and other MutationEvents have been deprecated by the W3C but there doesn't appear to be a replacement until DOM Level 4

See: "Why is the DOMSubtreeModified event deprecated in DOM level 3?"

Long story short, DOMSubtreeModified will still work and there is no reasonable alternative implemented across stable browsers.

Implementation of a DOM listener

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' );

DOM mutation events replacement

As far as I know there is no alternative (yet) so you are stuck with DOMAttrModified which is only supported in Firefox and Opera. In IE you have the onpropertychanged event but there is no way to get similar functionality in Chrome/Safari. There are a number of things you could do depending on what you are trying to accomplish and the browsers you are targetting:

  • define getters and setters to the attributes you want to monitor
  • override methods like document.createAttribute, attributes.setNamedItem, ...

I've been working on a cross-browser solution myself but without much success. You should stay away from mutation events all together since they are not cross-browser and very slow.
There are good reasons why they are deprecated. If you want to learn more read this:

  • http://www.w3.org/2008/webapps/wiki/MutationReplacement
  • http://www.quirksmode.org/dom/events/ > W3C events
  • http://robertnyman.com/javascript/javascript-getters-setters.html

DOMSubtreeModified - check if only first item in container has changed

You should filter out event target, using e.g:

$('.container').on("DOMSubtreeModified", function (e) {
if($(e.target).is('.item:first-child')) {
console.log(e.target);
}
});


Related Topics



Leave a reply



Submit