Detect element content changes with jQuery

JavascriptJqueryDom

Javascript Problem Overview


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?

Javascript Solutions


Solution 1 - Javascript

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/

Solution 2 - Javascript

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.

Solution 3 - Javascript

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?

Solution 4 - Javascript

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

Solution 5 - Javascript

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

Solution 6 - Javascript

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/

Solution 7 - Javascript

And with HTML5 we have native DOM Mutation Observers.

Solution 8 - Javascript

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).

Solution 9 - Javascript

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.

Solution 10 - Javascript

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

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

Solution 11 - Javascript

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

Solution 12 - Javascript

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.

Solution 13 - Javascript

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

Solution 14 - Javascript

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

Solution 15 - Javascript

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!

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionElzo ValugiView Question on Stackoverflow
Solution 1 - JavascriptKyle CureauView Answer on Stackoverflow
Solution 2 - JavascriptjrharshathView Answer on Stackoverflow
Solution 3 - JavascriptTM.View Answer on Stackoverflow
Solution 4 - JavascriptFDiskView Answer on Stackoverflow
Solution 5 - JavascriptColinView Answer on Stackoverflow
Solution 6 - JavascriptPim JagerView Answer on Stackoverflow
Solution 7 - JavascriptElzo ValugiView Answer on Stackoverflow
Solution 8 - JavascriptJohn ReidView Answer on Stackoverflow
Solution 9 - JavascriptEskat0nView Answer on Stackoverflow
Solution 10 - JavascriptArpitView Answer on Stackoverflow
Solution 11 - JavascriptAntony CarthyView Answer on Stackoverflow
Solution 12 - Javascriptuser669677View Answer on Stackoverflow
Solution 13 - JavascriptAndrew AtkinsonView Answer on Stackoverflow
Solution 14 - JavascriptSanchit GuptaView Answer on Stackoverflow
Solution 15 - JavascriptredsquareView Answer on Stackoverflow