JavaScript获取当前应用于元素的样式列表

时间:2015-12-15 01:43:22

标签: javascript html css

仅列出 呈现的样式,而不是未应用的任意样式

我已经尝试了许多方法来将样式应用于元素,但却出现了空白。

除非您能解决垃圾回收问题,否则请不要引用HEAD作为解决方案。

主要问题是,getComputedStyle将返回window.getComputedStyle(document.querySelector('ANY ELEMENT')).fill,几乎在任何情况下都 正确的样式,并且如果实际存在,则没有明显的方法可以使用应用与否。

以上例子不是唯一的问题; "rgb(0, 0, 0)"返回的大量规则是错误的,并且如果应用了页面,它们将彻底改变页面的外观。

静态解析不是一个选项,因为有些情况下.css文件位于没有跨源头的另一台服务器上;它也隐藏了getComputedStyle中常见的样式。

有没有办法获得所应用的样式列表而没有其他内容?

根据要求,此代码将演示此问题(在Chrome上):

document.styleSheets

编辑:我的答案包含适用于所有浏览器的代码。我保留上面保留评论线程。

2 个答案:

答案 0 :(得分:1)

以下是不需要检查深度的版本。 代码中的问题是在前一个元素中分配内联样式会影响下一个结果的getComputedStyle结果。这意味着getComputedStyle的值总是在循环中改变。您可以先将它存储在这样的数组中。

var all = document.getElementsByTagName('*');
tmpArr = []
for(var i in all) {
    if (all[i].style) {
        tmpArr[i] = window.getComputedStyle(all[i]).cssText;
    }
}
for(var i in all) {
    if (all[i].style) {
        all[i].style.cssText = tmpArr[i]; ;
    }
}
console.log("finish");

您可以将tmpArr[i] = window.getComputedStyle(all[i]).cssText;更改为tmpArr[i] = window.getComputedStyle(all[i]).cssText + "-webkit-text-fill-color:#691099!important";以测试其是否有效

如果打开检查器会很慢,因为内联样式太多,但如果您只需要将样式设置为内联样式,它将解决问题。

答案 1 :(得分:1)

部分答复(更新):

通过调用我的函数getRenderedStyles

,可以只获取活动样式
  

getRenderedStyles现在绕过活动样式表以获得更准确的输出。

function getRenderedStyles(element) {
    var tmpele, tmpstyle, elestyle, varstyle, elecolor, eletag;
    var styles   = {};
    var defstyle = {};
    elestyle   = window.getComputedStyle(element);
    elecolor   = elestyle.color; 
    eletag     = element.tagName;
    var frag = document.createDocumentFragment();
    frag.appendChild(document.documentElement);
    tmpele   = document.appendChild(document.createElement(eletag));
    tmpstyle = window.getComputedStyle(tmpele);
    styles['color']     = elecolor===tmpstyle.color?undefined:elecolor;
    tmpele.style.color  = elecolor; // workaround for color propagation on other styles 
    for (var i in tmpstyle)
        defstyle[i] = tmpstyle[i];
    tmpele.remove();
    document.appendChild(frag);
    varstyle = element.style;
    for (var i in varstyle) {
        if ((((typeof varstyle[i])==="string"))&&(i!=="cssText")) {
            if ((defstyle[i]!==elestyle[i]))
                styles[i] = elestyle[i];
        }
    }
    return styles;
}

遗憾的是,由于浏览器在某些情况下似乎仍会返回无效的样式,因此存在空洞。经常改变元素的位置。

要验证这一点,您可以运行以下代码,其中考虑了父/子继承,以尝试将当前样式正确应用于页面:

function DOMDepth(element) {
    var cur  = element;
    var deep = 0;
    while(cur.parentNode)
        deep++, cur = cur.parentNode;
    return deep;
}

function getElementsByDepth() {
    var all = document.getElementsByTagName('*');
    var depth_map = {};
    var deepest   = 0;
    for(var i in all) {
        var depth = DOMDepth(all[i]);
        deepest   = depth>deepest?depth:deepest;
        depth_map[depth] = depth_map[depth] || [];
        depth_map[depth].push(all[i]);
    }
    depth_map['deepest'] = deepest;
    return depth_map;
}

function inlineComputedStyles() {
    var depth_map = getElementsByDepth();
    for (var i = depth_map.deepest; i>0; i--) {
        var elements = depth_map[i];
        for (var j in elements) {
            var styles = getRenderedStyles(elements[j]);
            for (var k in styles) {
                elements[j].style[k] = styles[k];
            }
        }
    }
}

我已经测试了前面的内容并且可以确认它没有遇到问题中代码段的颜色问题。遗憾的是,我不确定为什么有些元素仍在转变,或者是否有办法解决它。

特别感谢Kit Fung指出继承问题。