Detect element content changes with jQuery


change() function works and detects changes on form elements, but is there a way of detecting when a DOM element's content was changed?

This does not work, unless #content is a form element

$("#content").change( function(){
    // do something
});

I want this to trigger when doing something like:

$("#content").html('something');

Also html() or append() function don't have a callback.

Any suggestions?

These are mutation events.

I have not used mutation event APIs in jQuery, but a cursory search led me to this project on GitHub. I am unaware of the project's maturity.


I know this post is a year old, but I'd like to provide a different solution approach to those who have a similar issue:

  1. The jQuery change event is used only on user input fields because if anything else is manipulated (e.g., a div), that manipulation is coming from code. So, find where the manipulation occurs, and then add whatever you need to there.

  2. But if that's not possible for any reason (you're using a complicated plugin or can't find any "callback" possibilities) then the jQuery approach I'd suggest is:

    a. For simple DOM manipulation, use jQuery chaining and traversing, $("#content").html('something').end().find(whatever)....

    b. If you'd like to do something else, employ jQuery's bind with custom event and triggerHandler

    $("#content").html('something').triggerHandler('customAction');
    
    $('#content').unbind().bind('customAction', function(event, data) {
       //Custom-action
    });
    

Here's a link to jQuery trigger handler: http://api.jquery.com/triggerHandler/


The browser will not fire the onchange event for <div> elements.

I think the reasoning behind this is that these elements won't change unless modified by javascript. If you are already having to modify the element yourself (rather than the user doing it), then you can just call the appropriate accompanying code at the same time that you modify the element, like so:

 $("#content").html('something').each(function() { });

You could also manually fire an event like this:

 $("#content").html('something').change();

If neither of these solutions work for your situation, could you please give more information on what you are specifically trying to accomplish?


what about http://jsbin.com/esepal/2

$(document).bind("DOMSubtreeModified",function(){
  console.log($('body').width() + ' x '+$('body').height());
})

This event has been deprecated in favor of the Mutation Observer API


Try to bind to the DOMSubtreeModified event seeign as test is also just part of the DOM.

see this post here on SO:

how-do-i-monitor-the-dom-for-changes


Try this, it was created by James Padolsey(J-P here on SO) and does exactly what you want (I think)

http://james.padolsey.com/javascript/monitoring-dom-properties/


And with HTML5 we have native DOM Mutation Observers.


It's not strictly a jQuery answer - but useful to mention for debugging.

In Firebug you can right-click on an element in the DOM tree and set up 'Break on Attribute Change':

Element right-click in Firebug with Break on Attribute Change highlighted

When an attribute is changed in a script, the debug window will appear and you can track down what it going on. There is also an option for element insertion and element removal below (unhelpfully obscured by the popup in the screengrab).


I'm developing tiny JS library called mutabor (https://github.com/eskat0n/mutabor) which intended to simplify usage of DOM Mutation Events. See demo.html for examples.


Try the livequery plugin. That seems to work for something similar I am doing.

http://docs.jquery.com/Plugins/livequery


Often a simple and effective way to achieve this is to keep track of when and where you are modifying the DOM.

You can do this by creating one central function that is always responsible for modifying the DOM. You then do whatever cleanup you need on the modified element from within this function.

In a recent application, I didn't need immediate action so I used a callback for the handly load() function, to add a class to any modified elements and then updated all modified elements every few seconds with a setInterval timer.

$($location).load("my URL", "", $location.addClass("dommodified"));

Then you can handle it however you want - e.g.

setInterval("handlemodifiedstuff();", 3000); 
function handlemodifiedstuff()
{
    $(".dommodified").each(function(){/* Do stuff with $(this) */});
}

You can add a callback option to html (,or any) function:

$.fn.oldHtml = $.fn.html;
$.fn.html = function(html,fn){
  fn = fn || function(){};
  var result =  this.oldHtml(html);
  fn();
  return result;
};
$('body').html(11,function(){alert("haha");});

Demo here.

You do the change on some element, not the element is forced to change by something that you have to catch.


I wrote a snippet that will check for the change of an element on an event.

So if you are using third party javascript code or something and you need to know when something appears or changes when you have clicked then you can.

For the below snippet, lets say you need to know when a table content changes after you clicked a button.

$('.button').live('click', function() {

            var tableHtml = $('#table > tbody').html();
            var timeout = window.setInterval(function(){

                if (tableHtml != $('#table > tbody').
                    console.log('no change');
                } else {
                    console.log('table changed!');
                    clearInterval(timeout);
                }

            }, 10);
        });

Pseudo Code:

  • Once you click a button
  • the html of the element you are expecting to change is captured
  • we then continually check the html of the element
  • when we find the html to be different we stop the checking

We can achieve this by using Mutation Events. According to www.w3.org, The mutation event module is designed to allow notification of any changes to the structure of a document, including attr and text modifications. For more detail MUTATION EVENTS

For Example :

$("body").on('DOMSubtreeModified', "#content", function() {
    alert('Content Modified'); // do something
});

Not possible, I believe ie has a content changed event but it is certainly not x-browser

Should I say not possible without some nasty interval chugging away in the background!