I need to watch for an attribute change on any of the children of a specific DOM element. So far, I have been using mutation events.
The problem was - they were buggy: e.g. under Chromium, DOMAttrModified
was not fired but DOMSubtreeModified
was. The problem was easy to solve: because according to the specification, DOMSubtreeModified
is fired if any of the other events is fired, so I just listened to DOMSubtreeModified
.
Anyway, Chromium, in the recent versions, stopped firing anything if an attribute has been modified.
The new Mutation Observer API, however, works flawlessly.
Until now, I only need to fire a callback upon ANY change of the subtree of a specific element - simply because nothing else is supposed to change - so I solved my problem by just using mutation events & mutation observer (when available) in the same piece of code.
However, now I need to do more powerful filtering of the events (e.g. on new node, on removed node) - so is there a library, possibly a jQuery plug-in, that would allow me to elegantly use both of these APIs - MutationObserver
if available and mutation events as a fallback, with the ability to filter for specific event types (e.g. element added, attribute changed).
E.g.
$("#test").watch({onNewElement: 1}, function(newElement){})
$("#test").watch({onNewAttribute: 1}, function(modifiedElement) {})
Or without jQuery
watchChanges("#test", {onNewElement: 1}, function(newElement){})
watchChanges("#test", {onNewAttribute: 1}, function(modifiedElement){})
observe() The MutationObserver method observe() configures the MutationObserver callback to begin receiving notifications of changes to the DOM that match the given options. Depending on the configuration, the observer may watch a single Node in the DOM tree, or that node and some or all of its descendant nodes.
MutationObserver is a Web API provided by modern browsers for detecting changes in the DOM. With this API one can listen to newly added or removed nodes, attribute changes or changes in the text content of text nodes.
The MutationObserver interface provides the ability to watch for changes being made to the DOM tree. It is designed as a replacement for the older Mutation Events feature, which was part of the DOM3 Events specification.
For example, to monitor an element we can now write: // The node to be monitored var target = $( "#content" )[0]; // Create an observer instance var observer = new MutationObserver(function( mutations ) { mutations. forEach(function( mutation ) { var newNodes = mutation. addedNodes; // DOM NodeList if( newNodes !==
Would this work?
http://darcyclarke.me/development/detect-attribute-changes-with-jquery/
$.fn.watch = function(props, callback, timeout){ if(!timeout) timeout = 10; return this.each(function(){ var el = $(this), func = function(){ __check.call(this, el) }, data = { props: props.split(","), func: callback, vals: [] }; $.each(data.props, function(i) { data.vals[i] = el.css(data.props[i]); }); el.data(data); if (typeof (this.onpropertychange) == "object"){ el.bind("propertychange", callback); } else if ($.browser.mozilla){ el.bind("DOMAttrModified", callback); } else { setInterval(func, timeout); } }); function __check(el) { var data = el.data(), changed = false, temp = ""; for(var i=0;i < data.props.length; i++) { temp = el.css(data.props[i]); if(data.vals[i] != temp){ data.vals[i] = temp; changed = true; break; } } if(changed && data.func) { data.func.call(el, data); } } }
For efficient DOM monitoring with jQuery, you might take a look at the jQuery Behavior Plugin (Disclaimer: I'm the author) which utilizes a optimized version of Live Query. I'm using it in several products for 3 year now, without any problems.
Edit: Listening for attribute changes would work like this:
$.behavior({
'div:first': {
'changeAttr': function (event, data) {
console.log('Attribute "' + data.attribute + '" changed from "' + data.from + '" to "' + data.to + '"');
}
}
});
$('div:first').attr('foo', 'bar');
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With