edkeveked
edkeveked

Reputation: 18381

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

Upvotes: 7

Views: 4203

Answers (1)

Kaiido
Kaiido

Reputation: 136707

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>

Upvotes: 11

Related Questions