I have a problem: I have table that is updated from time to time by AJAX script. This update is called from Chrome plugin which I don't want to change. So I'd like to add some kind of jQuery trigger that on change of table cells will call my own function.
Is it possible? I tried event onChange but it doesn't work (it's for input if I'm right)
Thanks in advance!
Using setInterval() You can constantly monitor the content of Your table and compare it with previous content. If the content is different, then the table was changed.
$(function() {
var previous = $("#mytable").text();
$check = function() {
if ($("#mytable").text() != previous) {
myOwnFunction();
}
previous = $("#mytable").text();
}
setInterval(function() { $check(); }, 1000);
}
function myOwnFunction() {
alert("CHANGED");
}
onchange
is designed for use with inputs like <select>
- so wont work in this context. There are specific dom related events you can use (like DOMSubtreeModified
), but these aren't cross-browser and have varying implementations (they may even now be deprecated):
http://en.wikipedia.org/wiki/DOM_events
MutationEvents
as mentioned above have seemingly been replaced by MutationObservers
which I have not used yet myself... but sounds like it would do what you need:
http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#mutation-observers
Other than that you can fallback to a setInterval
handler that will listen for any change in the HTML within your target element... when it changes you fire a function.
function watch( targetElement, triggerFunction ){
/// store the original html to compare with later
var html = targetElement.innerHTML;
/// start our constant checking function
setInterval(function(){
/// compare the previous html with the current
if ( html != targetElement.innerHTML ) {
/// trigger our function when a change occurs
triggerFunction();
/// update html so that this doesn't keep triggering
html = targetElement.innerHTML;
}
},500);
}
function whenChangeHappens(){
alert('this will trigger when the html changes in my_target');
}
watch( document.getElementById('my_target'), whenChangeHappens );
If you want to jQueryify the above into something you can apply to any element it would easy to modify:
/// set up the very simple jQuery plugin
(function($){
$.fn.domChange = function( whenChanged ){
/// we want to store our setInterval statically so that we
/// only use one for all the listeners we might create in a page
var _static = $.fn.domChange;
_static.calls = [];
_static.iid = setInterval( function(){
var i = _static.calls.length;
while ( i-- ) {
if ( _static.calls[i] ) {
_static.calls[i]();
}
}
}, 500 );
/// step each element in the jQuery collection and apply a
/// logic block that checks for the change in html
this.each (function(){
var target = $(this), html = target.html();
/// by adding the function to a list we can easily switch
/// in extra checks to the main setInterval function
_static.calls.push (function(){
if ( html != target.html() ) {
html = target.html();
whenChanged();
}
});
});
}
})(typeof jQuery != undefined && jQuery);
/// example code to test this
(function($){
$(function(){
$('div').domChange( function(){
alert('I was changed!');
} );
});
})(typeof jQuery != undefined && jQuery);
Obviously the above is a very simple version, it should be extended to handle adding and removing of listeners.