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
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.
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.
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.
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>
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With