Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Detect dom element style change using Mutation Observer

Using MutationObserver I would like to detect a dom element change due to media query in a component.

But the MutationObserver fails to trigger an event when the style changes.

detectDivChanges() {
    const div = document.querySelector('.mydiv');
    const config = { attributes: true, childList: true, subtree: true };
    const observer = new MutationObserver((mutation) => {
      console.log("div style changed");
    })
    observer.observe(div, config);
  }
}
<div class="mydiv">test</div>
.mydiv {
  height: 40px;
  width: 50px;
  background-color: red;
}

@media screen and (min-width : 500px) {
  .mydiv {
    background-color: blue;
  }
}

Here is a live version of the code

like image 977
edkeveked Avatar asked Jun 19 '18 13:06

edkeveked


People also ask

How do you observe a DOM change?

One way to watch for DOM changes in our JavaScript web app is to use the MutationObserver constructor. For instance, we can write: const observer = new MutationObserver((mutations, observer) => { console. log(mutations, observer); }); observer.

How is Mutation Observer used?

The first line creates a new MutationObserver using the MutationObserver() constructor. The argument passed into the constructor is a callback function that will be called on each DOM change that qualifies. The way to determine what qualifies for a particular observer is by means of the final line in the above code.

How do you use Mutation observer in JavaScript?

Introduction to the JavaScript MutationObserver API When the DOM nodes change, you can invoke a callback function to react to the changes. Third, call the observe() method to start observing the DOM changes. The observe() method has two parameters. The target is the root of the subtree of nodes to monitor for changes.


Video Answer


1 Answers

Mutation Observer can observe changes being made to the DOM tree.
When your CSS MediaQuery changes, the DOM tree is not affected whatsoever, so the MutationObserver won't catch it.

Your confusion comes from the fact that HTMLElements do have a style attribute. This attibute is indeed part of the DOM tree. But this style attribute is not the style that is applied on the element. This attribute does declare a StyleSheet that the CSSOM will parse and use if needed, but the CSSOM and the DOM are two separate things.

So what you want to detect is a CSSOM change not a DOM one (the style attribute doesn't change when you resize your screen), and this, a MutationObserver can't do it.

However, since you are willing to listen for a CSS MediaQuery change, then you can use the MediaQueryList interface and its onchange event handler:

const mediaQuery = window.matchMedia('screen and (min-width : 500px)');
mediaQuery.onchange = e => {
  console.log('mediaQuery changed', 'matches:', mediaQuery.matches);
}
.mydiv {
  height: 40px;
  width: 50px;
  background-color: red;
}

@media screen and (min-width : 500px) {
  .mydiv {
    background-color: blue;
  }
}
<div class="mydiv">test</div>
like image 177
Kaiido Avatar answered Oct 15 '22 13:10

Kaiido