Fire jQuery event on div change
Asked Answered
M

3

59

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?

Mokpo answered 12/2, 2011 at 18:15 Comment(0)
B
71

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

Update

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>"]

Update 2

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.

Birk answered 12/2, 2011 at 18:31 Comment(5)
Thank you very much! It is unfortunate that IE does not implement this event... :-(Mokpo
Yeah, if you plan on supporting IE, you must periodically check for innerHTML. No other way. :( Check out my update. ;)Birk
Here is the solution for IE: https://mcmap.net/q/189736/-jquery-watch-div/…Yellowbird
so awesome! i would have never thought to use DOMNodeInsertedMorez
This is deprecated developer.mozilla.org/en-US/docs/Web/Guide/Events/…Blasien
H
6

try something like this...

    $('#divId').bind('DOMNodeInserted', function(event) {
             alert('inserted ' + event.target.nodeName + // new node
           ' in ' + event.relatedNode.nodeName); // parent
       });

IE doesn't support this propert but i think the nearest to this is the propertychange event, which fires in response to a change in an attribute or CSS property of an element, but it doesn't fire in response to innerHTML changing, which would have been close to what you wanted.

one more feasible solution is to override manipulation function of jquery...

Have a look on this discussion..Preferred way of modifying elements that have yet to be created (besides events)

Hawsepipe answered 12/2, 2011 at 18:36 Comment(0)
S
2

There is no such an event (onChange) in javascript nor jQuery, you would have to create a custom event.

One solution could be using lowpro to attach a behavior in this element you want to be controlled, this behavior would serialize the element and then build a poll that checks every x miliseconds to see if the element has changed, if changed then trigger your custom event on that element.

You have some examples on how to use lowpro with jQuery here: http://www.learningjquery.com/2008/05/using-low-pro-for-jquery

Good luck!

Sollars answered 12/2, 2011 at 18:34 Comment(5)
There is, DOMNodeInserted, but IE doesn't support it.Birk
Still thats not the event he is looking for the element might change withtout having a Node Inserted or removed.... Imagine it only contains text and the text is removed, DOMNodeInserted wouldnt fire and still the element is changed...Sollars
See my answer. I've included DOMNodeRemoved, too.Birk
@Nyuszika7H I dont think you read the question, he says the content might just be changed, if you have a div like <div>hello</div> and you chnage the content to <div>bye</div> there is no node removed or insertedSollars
I've updated my answer with DOMSubtreeModified. It should now work fine in non-IE browsers.Birk

© 2022 - 2024 — McMap. All rights reserved.