HTML table onChange

12,678

Solution 1

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

setInterval

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

jQuery Plugin

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.

Solution 2

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");
}
Share:
12,678
Gricha
Author by

Gricha

Updated on June 09, 2022

Comments

  • Gricha
    Gricha almost 2 years

    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!

  • Gricha
    Gricha over 11 years
    Since my table is sortable setInterval won't do the job - table doesn't change by reordering for me - it changes because cell content changed. That's why plugin and event attached to every cell worked out perfectly. Thank you!