Snorlax Snorlax - 6 months ago 24
jQuery Question

Check if a table's rows are being changed

I would like to use a MutationObserver (or anything else at this point) to listen for changes in my table. My

table -> tbody -> tr
elements can be changed in various ways, such as:


  1. Filtering through search (which toggles an
    <tr>
    -element to show or hide)

  2. Filtering through checkboxes (again toggles them)

  3. Removes
    <tr>
    -elements



By using a MutationObserver, I can go and check for changes in the table. It works when I remove an element (because the childList and subtree changes), but it does not trigger, when an element's attribute changes. Here's my observer:

var observer = new MutationObserver(function(mutations, observer) {
updateTable();
});
observer.observe(document.querySelector('#reports'), { childList: true, characterData: true, subtree: true });


My HTML:

<table id="reports">
<thead>........
<tbody>
<tr><td>Stuff here 1</td></tr>
<tr><td>Stuff here 2</td></tr>
<tr><td>Stuff here 3</td></tr>
</tbody>
</table>


My
updateTable()
function is pretty simple: It updates the
table -> tbody -> tr
-element backgrounds. This means, that if I check for attribute change in the observer, it will run into an endless loop, because:


Oh someone hid the
<tr>
element! Let me go change the background. Oh look, someone changed the background! Let me change the background. Oh look! .... Endless loop


How would I go on about this? Thanks

Answer

Disclaimer: It may not be a performant solution.

But what about deactivating the observer before executing the callback ? Something like

var observe = function(){
    var observer = new MutationObserver(function(mutations, observer) {
         observer.disconnect(); // stop watching changes
         updateTable(); // do your changes
         observe(); // start watching for changes again
    });
    observer.observe(document.querySelector('#reports'), { childList: true, attributes: true, subtree: true });
}

So the first time you would just do

observe();

when you change #reports, it will fire the MutationObserver, you disconnect it, so you can do your DOM changes, and then you would place the observer again.

Code not tested, so let me know if this works for you

Comments