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?
This question is related to
javascript
jquery
dom
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?
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:
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.
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");});
You do the change on some element, not the element is forced to change by something that you have to catch.
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
});
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:
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.
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/
Try to bind to the DOMSubtreeModified
event seeign as test is also just part of the DOM.
see this post here on SO:
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!
And with HTML5 we have native DOM Mutation Observers.
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/
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
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':
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).
Source: Stackoverflow.com