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 theMutationEvent
interface and theMutationNameEvent
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
Where's the Connection Between Index.HTML and Index.Js in a Create-React-App Application
Pass a JavaScript Variable Value into Input Type Hidden Value
Clean Way to Programmatically Use CSS Transitions from Js
Center an Image Vertically and Horizontally Using CSS
What Is a Text Node, Its Uses? //Document.Createtextnode()
How to Save Canvas Animation as Gif or Webm
HTML Mobile -Forcing the Soft Keyboard to Hide
When Loading an HTML Page via Ajax, Will Script Tags Be Loaded
How to Resize HTML Canvas Element
How to Retain the Scroll Position of a Scrollable Area When Pressing Back Button
Making Sure at Least One Checkbox Is Checked
How to Append Timestamp to the JavaScript File in <Script> Tag Url to Avoid Caching
Fix First Column of a Bootstrap Table
How to Get Color Value from Gradient by Percentage with JavaScript
Angular Ie Caching Issue for $Http
Why How to Access Typescript Private Members When I Shouldn't Be Able To