繁体   English   中英

MutationObserver 和当前/计算 CSS 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 内容。

实现此功能的最佳方法是什么? 我想我正在经历一种风格变化的突变,但我怀疑这是否存在。

这对我有用......

  1. 使用变异观察器来捕获样式属性的更改...

     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

  2. 使用变异观察器捕获新stylelink元素,添加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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM