3

I'm writing a function using the mutation observer with jQuery to register changes to the DOM, specifically when a new node is added so i can change its content:

$("SELeCTOR GOOD" ).click(function(){
  var targetNode = $(this).find('.content').get(0);
  var config = { attributes: true, childList: true, subtree: true, attributeOldValue: true };

  // Callback function to execute when mutations are observed
  var callback = function(mutationsList) {
      for(var mutation of mutationsList) {
          if (mutation.type == 'childList') {
              var courses = $(targetNode).find('.courses').get(0);
              $(courses).find('.coursebox.clearfix').each(function( index,item ) {
                var attacherURL = $(item).find('.coursename a').attr('href');
                var moreInfoURL = '<a class="btn btn-outline-primary pull-right" href="'+attacherURL+'">More info</a>';

                var oldHTML = $(item).find('div.moreinfo').html();
                var newHTML = moreInfoURL + oldHTML;
                //this following line is supposed to replace the html, but it creates an infinite loop
                $(item).find('div.moreinfo').html(newHTML);
                //end
              });
          }
          else if (mutation.type == 'attributes') {
              console.log('The ' + mutation.attributeName + ' attribute was modified.');
          }
      }
  };

I've tried append/prepend as well, but everything creates the same infinite loop. As usual, any help is greatly appreciated.

Regards

That guy
  • 135
  • 2
  • 10
Brandon
  • 135
  • 2
  • 12

1 Answers1

5

Well, your modification causes another mutation, which results in you modifying it again, causing an infinite loop. A simple solution is to add a class to your element to mark it as already processed, and ignore already processed nodes (nodes that have that class). Another is just check if the dev.morinfo alreade has moreInfoURL inside it, and ignore if it already does

juvian
  • 15,875
  • 2
  • 37
  • 38
  • thanks, i was using a data attribute, but this did the trick better! – Brandon Jun 18 '18 at 20:31
  • 1
    This made my day, after a whole day searching for a solution. How simple things can be sometimes. Just added a class and after that checked if the class exists with record.target.classList.contains('chatStatusUpdated') – NME New Media Entertainment Aug 01 '21 at 03:55