![](/img/trans.png)
[英]Can I use a MutationObserver to listen for changes on computed styles?
[英]MutationObserver and current/computed CSS styles
我正在使用 MutationObserver 来查找添加到 web 页面的图像。 由于许多图像是通过 CSS background-image
属性显示的,因此我正在检查当前/计算的 CSS 样式以及查找img
标签,例如...
var hasBackgroundImage = function(node) {
var nodeStyle = node.currentStyle || getComputedStyle(node, null);
return (
nodeStyle &&
nodeStyle.backgroundImage &&
nodeStyle.backgroundImage != "none"
);
};
但是,似乎在触发突变事件的节点与正在应用的 CSS 规则之间存在延迟,因此在突变事件期间似乎没有backgroundImage
图像,即使稍后会有。 当代码在调试期间工作(使用断点单步执行)但在运行时不起作用时,我注意到了这一点。 使用setTimeout
延迟突变事件处理也可以,但要确定延迟需要相当大并且从页面到页面的变化(我不确定何时保证应用 CSS 规则)。 一个可能的原因可能只是延迟加载或注入 CSS 内容。
实现此功能的最佳方法是什么? 我想我正在经历一种风格变化的突变,但我怀疑这是否存在。
这对我有用......
使用变异观察器来捕获样式属性的更改...
var observer = new MutationObserver(parseMutations); observer.observe(document, { ... attributes: true, attributeFilter: ["style"] }); ... if (mutation.attributeName) //we'll assume it's "style" parseNode(mutation.target); //check for style.backgroundImage and call filterNode()
这既适用于setAttribute("style", ...)
和element.style.whatever = something
。
使用变异观察器捕获新style
和link
元素,添加onload
事件并解析适用的节点...
var stylenodes = ["STYLE", "LINK"]; ... for (var i = 0; i < mutation.addedNodes.length; i++) { var node = mutation.addedNodes[i]; var nodeName = node.nodeName.toUpperCase(); if (stylenodes.indexOf(nodeName) !== -1) node.addEventListener("load", styleLoaded); ... //catch loading of stylenodes and parse all new rules var currentLoadedStyles = []; var styleLoaded = function() { //check all styles and look for one that has just added some rules for (var i = 0; i < document.styleSheets.length; ++i) { if (document.styleSheets[i].rules && document.styleSheets[i].rules.length > 0 && currentLoadedStyles.indexOf(document.styleSheets[i]) == -1) { currentLoadedStyles.push(document.styleSheets[i]); parseNewStyle(document.styleSheets[i].rules); } } }; //look for rules with background images and re-filter all nodes it applies to var parseNewStyle = function(rules) { for (var i = 0; i < rules.length; ++i) { //if any rule contains a background-image (could look for anything here really) if (rules[i].style && rules[i].style.backgroundImage && rules[i].style.backgroundImage != "none") { //get all affected nodes and re-parse them var nodes = document.querySelectorAll(rules[i].selectorText); for (var j = 0; j < nodes.length; ++j) filterNode(nodes[j]); } } };
我使用https://github.com/keithclark/ComputedStyleObserver观察计算的样式“显示”并根据其值进行更改。 这是代码:(在我的情况下,它是一个 Vue.js 项目)
setup(){
let observer = null;
const collapsableItemsOnNavbar = ref(null);
onMounted(() =>{
// This is to make sure that the Profile menu displays correctly between screen sizes
const callback = entries => {
entries.forEach(entry => {
console.log(`Property '${entry.property}' changed from '${entry.previousValue}' to '${entry.value}'`);
nextTick(() => {
let displayType = entry.value;
console.log(displayType);
if(displayType === 'none' || displayType === 'block'){
// We are in a small screen, don't display the profile picture
app.onNavbarCollapseChanged(true);
}
else{
// We are in a bigger screen, display the profile picture
app.onNavbarCollapseChanged(false);
}
});
});
}
observer = new ComputedStyleObserver(callback, ['display']);
observer.observe(collapsableItemsOnNavbar.value);
});
onBeforeUnmount(() =>{
observer.disconnect();
});
return {
collapsableItemsOnNavbar,
};
},
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.