使用 Mutation Observer 检测 dom 元素样式更改

edk*_*ked 6 javascript angular

使用MutationObserver我想检测由于组件中的媒体查询而导致的 dom 元素更改。

但是 MutationObserver 在样式改变时无法触发事件。

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);
  }
}
Run Code Online (Sandbox Code Playgroud)
<div class="mydiv">test</div>
Run Code Online (Sandbox Code Playgroud)
.mydiv {
  height: 40px;
  width: 50px;
  background-color: red;
}

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

这是代码的实时版本

Kai*_*ido 7

Mutation Observer 可以观察对 DOM 树所做的更改。
当您的 CSS MediaQuery 更改时,DOM 树不会受到任何影响,因此 MutationObserver 不会捕获它。

您的困惑来自HTMLElement确实具有style属性这一事实。这个属性确实是 DOM 树的一部分。但是这个style属性并不是应用在元素上的样式。该属性确实声明了CSSOM将在需要时解析和使用的样式表,但 CSSOM 和 DOM 是两个独立的东西。

因此,您要检测的是 CSSOM 更改而不是 DOM 更改(style调整屏幕大小时属性不会更改),而 MutationObserver 无法做到这一点。

但是,由于您愿意监听 CSS MediaQuery 更改,因此您可以使用MediaQueryList接口及其onchange事件处理程序:

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

@media screen and (min-width : 500px) {
  .mydiv {
    background-color: blue;
  }
}
Run Code Online (Sandbox Code Playgroud)
<div class="mydiv">test</div>
Run Code Online (Sandbox Code Playgroud)

  • @edkeveked `style` 属性是,但 calculateStyle 不是。您的 CSS 不会修改 DOM。至于*“那么考虑什么样的属性”*,所有的DOM属性。 (4认同)