Search code examples
javascriptjquerycss

How to insert MutationObserver into jQuery code


I'm relatively new to jQuery.

EDITED QUESTION: So instead of using setInterval to keep running the code every 400ms, I was given a tip that MutationObserver would be a better solution. I've now read about it online, I understand HOW it works, but I'm not experienced enough to implement it into my code. Is anyone willing to help? It's way easier for me to see it in practice so I can do this myself next time.

Here is the code:

$(document).ready(function() {
    const numbersToCheck = ['207747', '207746', '207743', '207742', '207739', '207741', '207744', '215364', '215371', '215406', '215405', '215366', '215365', '239511', '239512', '239513'];
    $('.mini-product').each((index, mp) => {
      let productNumber = $(mp).find('.product-number').first().text().trim();
      if (numbersToCheck.includes(productNumber)) {
        $(mp).find('.checkout-spacing').each((csi, cs) => {
          $(cs).css('display', 'none');
        });
      }
    });
});

This is what I found and read about MutationObserver: https://gabrieleromanato.name/jquery-detecting-new-elements-with-the-mutationobserver-object


Solution

  • Working example of how to implement a MutationObserver (JSFiddle):

    $(document).ready(function() {
      
      setTimeout(() => {
        $('#container').append("<div class='mini-product'>m4</div>");
      }, 1000);
      
      const numbersToCheck = ['207747', '207746', '207743', '207742', '207739', '207741', '207744', '215364', '215371', '215406', '215405', '215366', '215365', '239511', '239512', '239513'];
      
      // Initial swipe
      // This may not be needed as I'm pretty sure the observer will trigger initially for the elements that are already on the HTML
      $('.mini-product').each((index, mp) => {
          // Your logic
      });
        
      // Now we watch for new elements
      const observer = new MutationObserver(() => {
        if ($('.mini-product').length) {
          console.log('Change detected!!');
          // Repeat logic here for the new element
          // observer.disconnect(); for ending the observer, though in your case maybe you don't want that at all
        }
      });
      
      // Param 1 of observe() must be a Node - document is a valid Node, but not advisable, limit the watcher to as small a context as possible
      observer.observe(document.getElementById('container'), {
        childList: true,
        subtree: true
      });
      
    });
    

    In short what is happening here is that you declare a observer that is going to watch the context you pass as the first parameter to the observe() function and then trigger the callback function you passed in the declaration when changes occur.

    Note that here when the observer is triggered I'm looking for ALL the "mini-product" elements. You need to filter the previous ones or use the parameter the MutationObserver provides for your callback function to check exactly what has changed.

    So:

      const observer = new MutationObserver(changes => {
        if ($('.mini-product').length) {
          console.log('Change detected!!');
          console.log(changes);
          // Repeat logic here for the new element
          // observer.disconnect(); for ending the observer, though in your case maybe you don't want that at all
        }
    

    Check the documentation for more details about this param and others.