Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

MutationObserver not working for children

Apologies in advance for what is probably a simple question and appalling javascript below;

My problem is as follows, there is a banner on a site that goes through four images every few seconds. I am trying to push an "impression" into the dataLayer to be picked up by GTM. To display the next image it has been made (not by myself) to change the z-index from 0 to 1 of the next banner image. I tried initially to get the mutation observer to work on just one image. This worked but I soon found out that the z-index value actually changes about 3 times before settling on 1, so that actually fired 3 impressions each time. Ideally however I would like it all to work by looking at the parent div (and observing childList) and only fire one impression per banner image, but when I try that it just says 'the provided node was null', I wonder if it is to do with the fact that only the children's style attributes are changing and nothing else?

The banner HTML is (when imagePane2 is shown);

<div id="rotator_10690" class="imageRotator Homepage_Middle_Banner_Rotator">
<div class="imagePane Homepage_Middle_Banner_imagePane imagePane1" style="left: 0px; top: 0px; position: absolute; z-index: 0; opacity: 1; display: none;">
<div class="imagePane Homepage_Middle_Banner_imagePane imagePane2" style="left: 0px; top: 0px; position: absolute; z-index: 1;">
<div class="imagePane Homepage_Middle_Banner_imagePane imagePane3" style="left: 0px; top: 0px; position: absolute; z-index: 0; display: none;">
<div class="imagePane Homepage_Middle_Banner_imagePane imagePane4" style="left: 0px; top: 0px; position: absolute; z-index: 0; display: none;">

My script for the parent div is

<script>
// select the target node
var target = document.querySelector('.rotator_10690');

//call mutation observer api
var MutationObserver = window.MutationObserver || window.WebKitMutationObserver;
 
// create an observer instance
var observer = new MutationObserver(function(mutations) {
  mutations.forEach(function(mutation) {
      if(mutation.type==="attributes" && mutation.target.className.indexOf("imagePane")) {
         observer.disconnect();
         dataLayer.push({'event': 'paneImpression'});

      }
  });
});
 
var disconnect = observer.disconnect();
// configuration of the observer:
// pass in the target node, as well as the observer options
var config = { attributes: true, childList: true }
observer.observe(target, config);

And for just the imagePane2 (I tried mutations.some here with return false, to try to stop it after it received the first mutation, but this didn't work. I also had zIndex==="1" in here as well but that still meant 3 or more impressions firing each time.).

<script>
// select the target node
var target = document.querySelector('.imagePane2');

//call mutation observer api
var MutationObserver = window.MutationObserver || window.WebKitMutationObserver;
 
// create an observer instance
var observer = new MutationObserver(function(mutations) {
  mutations.some(function(mutation) {
      if(mutation.type==="attributes" && mutation.target.className.indexOf("imagePane2")) {
         observer.disconnect();
         dataLayer.push({'event': 'paneImpression', 'pane': 'two'});

         return false;

      }
  });
});
 
var disconnect = observer.disconnect();
// configuration of the observer:
// pass in the target node, as well as the observer options
var config = { attributes: true }
observer.observe(target, config);


 

</script>

Any help anyone could offer would be greatly appreciated, I have tried looking everywhere but couldn't get anything to work.

Thank you

like image 927
Matt Avatar asked Jul 03 '15 07:07

Matt


People also ask

How MutationObserver works?

Overview. MutationObserver is a Web API provided by modern browsers for detecting changes in the DOM. With this API one can listen to newly added or removed nodes, attribute changes or changes in the text content of text nodes.

What is Mutation observer?

The MutationObserver interface provides the ability to watch for changes being made to the DOM tree. It is designed as a replacement for the older Mutation Events feature, which was part of the DOM3 Events specification.


1 Answers

{ attributes: true, childList: true }

asks for mutations due to changes to the attributes of .rotator_10690 and for mutations due to changes to the list of elements that are children of the code. childList literally listens for changes to the list of children, it doesn't listen for changes to the children themselves.

If you want essentially get all mutations to all children, the same way DOM events propagate up the tree, you'd want to add

subtree: true  
like image 101
loganfsmyth Avatar answered Nov 02 '22 07:11

loganfsmyth