I have a div whose content may change in various ways: for instance its whole content may be reloaded via innerHTML, or nodes may be added via DOM methods. This in turn may happen via native Javascript or indirectly via calls the jQuery API or via other libraries.
I want to execute some code when the content of the div changes, but I have absolutely no control on how it will change. Indeed I am designing a widget that may be used by other people, who are free to change the content of their divs the way they prefer. When the inner content of this div changes, the shape of the widget may have to be updated as well.
I'm using jQuery. Is there a way to capture the event that the content of this div has changed, however it happened?
Approach: In jQuery, there is no provision to trigger an event on class change. An alternative method is to manually raise an event when you programmatically change the class using the trigger() function. The trigger() function will raise an event whenever the class of the button is changed.
jQuery change() MethodThe change() method triggers the change event, or attaches a function to run when a change event occurs. Note: For select menus, the change event occurs when an option is selected.
Specification says: The onchange event occurs when a control loses the input focus and its value has been modified since gaining focus. This attribute applies to the following elements: INPUT, SELECT, and TEXTAREA. So no, it is not possible like this.
jQuery trigger() MethodThe trigger() method triggers the specified event and the default behavior of an event (like form submission) for the selected elements. This method is similar to the triggerHandler() method, except that triggerHandler() does not trigger the default behavior of the event.
You can use DOMNodeInserted
and DOMNodeRemoved
to check if elements are added or removed. Unfortunately, IE doesn't support this.
$('#myDiv').bind('DOMNodeInserted DOMNodeRemoved', function(event) { if (event.type == 'DOMNodeInserted') { alert('Content added! Current content:' + '\n\n' + this.innerHTML); } else { alert('Content removed! Current content:' + '\n\n' + this.innerHTML); } });
You could save the initial contents and future changes with .data()
. Here's an example.
var div_eTypes = [], div_changes = []; $(function() { $('#myDiv').each(function() { this['data-initialContents'] = this.innerHTML; }).bind('DOMNodeInserted DOMNodeRemoved', function(event) { div_eTypes.concat(e.type.match(/insert|remove/)); div_changes.concat(this.innerHTML); }); });
Example output:
> $('#myDiv').data('initialContents'); "<h1>Hello, world!</h1><p>This is an example.</p>" > div_eTypes; ["insert", "insert", "remove"] > div_changes; ["<iframe src='http://example.com'></iframe>", "<h4>IANA — Example domains</h4><iframe src='http://example.com'></iframe>", "<h4>IANA – Example domains</h4>"]
You may want to include DOMSubtreeModified
as well, because I've found out that DOMNodeInserted
and DOMNodeRemoved
don't trigger if an element's innerHTML
is replaced directly. It still doesn't work in IE, but at least it works fine in other browsers.
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