Search code examples
javascriptjquerymutation-observers

MutationObserver - getting "TypeError: MutationObserver.observe: Argument 1 does not implement interface Node."


I'm trying to detect the height of an element set dynamically by an image slider plugin and use it to set the height of a container.

Getting "TypeError: MutationObserver.observe: Argument 1 does not implement interface Node."

I checked MutationObserver documentation and its options. Saw that

At a minimum, one of childList, attributes, and/or characterData must be true when you call observe(). Otherwise, a TypeError exception will be thrown.

and I am setting attributes to true but still getting the typeError

jQuery(document).ready(function($){
  // Callback function to execute when mutations are observed
  const callback = function(mutationsList, observer) {
      for(const mutation of mutationsList) {
          console.log('The ' + mutation.attributeName + ' attribute was modified.');
      }
  };

  const observer = new MutationObserver(callback);

  //set up your configuration
  const config = { attributes:true, subtree: false };

  var changingContainer = $('.soliloquy-viewport');

  //start observing
  observer.observe(changingContainer, config);
  
  //change height on button press
  function changeHeight(){
    changingContainer.height(Math.floor((Math.random() * 100) + 20));
  }
  $("#height").click(changeHeight);
});
.soliloquy-viewport{
  background: yellow;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/1.12.4/jquery.min.js"></script>

<div class="soliloquy-viewport">
  Hello
</div>
<button id="height">
change height
</button>


Solution

  • MutationObervers only work on an Element object, not jQuery objects. Change the first argument of the observe() to the underlying Element by using get() like this:

    observer.observe(changingContainer.get(0), config);
    

    Or by accessing the jQuery object by index like this:

    observer.observe(changingContainer[0], config);
    

    jQuery(document).ready(function($) {
      let $changingContainer = $('.soliloquy-viewport');
      
      const observer = new MutationObserver((ml, o) => {
        for (const m of ml) {
          console.log('The ' + m.attributeName + ' attribute was modified.');
        }
      });
      
      observer.observe($changingContainer.get(0), {
        attributes: true,
        subtree: false
      });
    
      //change height on button press
      $("#height").click(() => $changingContainer.height(Math.floor((Math.random() * 100) + 20)));
    });
    .soliloquy-viewport {
      background: yellow;
    }
    <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/1.12.4/jquery.min.js"></script>
    
    <div class="soliloquy-viewport">Hello</div>
    <button id="height">change height</button>

    Note that this only works for a single element. For multiple elements with the same class, you will need to loop through them and apply the MO individually.