3

我可以使用 document.stylesheets 获取元素的所有 css 属性,但其中一些属性不是活动的,因为这些属性被覆盖了。在 firebug 中(chrome 开发者工具也有这个特性),如果有一个被覆盖的 css 属性,你会看到类似这样的东西: 在此处输入图像描述

我能想到的唯一方法是比较元素的活动 css 属性(在 jQuery 中$(element).css(property))和定义的 css 属性,document.stylesheets但这不是一种可靠的方法。有什么建议吗?

4

3 回答 3

6

在 webkit 中,你可以使用getMatchedCSSRules来实现你想要的。它按照浏览器应用的继承顺序返回一个 CSS 规则集,这是 webkit 检查器前一段时间使用的。对于像 Firefox 这样的基于 Gecko 的浏览器,这里似乎有一个可用的 polyfill ,虽然我没有测试过。

一个基本的、有效的解决方案

以下代码也可用作小提琴

因为getMatchedCSSRules 仅适用于内联样式表,所以您首先必须内联链接的样式表:

function inlineStyles() {
    var stylesheets = document.getElementsByTagName('link'),
        head = document.getElementsByTagName('head')[0];

    for (var i = 0; i < stylesheets.length; i++) {
        if (stylesheets[i].getAttribute('rel') == 'stylesheet') {
            (function (stylesheet) {
                var xmlhttp = new XMLHttpRequest();
                xmlhttp.open("GET", stylesheet.getAttribute('href'), true);
                xmlhttp.onreadystatechange = function () {
                    if (xmlhttp.readyState == 4 && xmlhttp.status == 200) {
                        var inlineStyle = document.createElement('style');
                        inlineStyle.setAttribute('type', 'text/css');
                        inlineStyle.innerText = xmlhttp.responseText;
                        head.replaceChild(inlineStyle, stylesheet);
                    }
                };
                xmlhttp.send();
            })(stylesheets[i]);
        } else {
            continue;
        }
    };
}

然后,大块:这是第一枪,随意改进。它可以处理inherit规​​则和最多一个!important定义,仅此而已。对于非常复杂的设置,必须改进:

function getStyle(s, id) {
    var element = typeof id === 'string' ? document.getElementById(id) : id,
        css = window.getMatchedCSSRules(element),
        style = window.getComputedStyle(element),
        value = style[s],
        styles = [],
        rules = [],
        inherited, currentRule;

    // if there's a computed style, start calculation
    if (value) {

        // add matched rules if there are any
        if (css) {
            for (var i = 0; i < css.length; i++) {
                styles.push(css[i]);
            }
        }

        // add the element style attribute as a matched rule
        styles.push({
            style: element.style,
            cssText: 'element.style {' + element.getAttribute('style') + ' }'
        });

        for (var i = styles.length - 1; i >= 0; i--) {
            var def = styles[i],
                rule = {
                    index: rules.length,
                    style: s,
                    value: styles[i].style[s],
                    cssText: def.cssText
                };

            if (rule.value == 'inherit' && !currentRule) {
                if (inherited = getInherited(element, s, value)) {
                    rule.inheritedFrom = inherited;
                    currentRule = rule;
                    inherited = undefined;
                } else {
                    rules.push(rule);
                }
            } else if (rule.value == 'inherit' && currentRule && isImportant(s, value, def.cssText)) {
                if (inherited = getInherited(element, s, def)) {
                    rule.inheritedFrom = inherited;
                    rules.splice(currentRule.index, 0, currentRule);
                    currentRule = rule;
                    inherited = undefined;
                } else {
                    rules.push(rule);
                }
            } else if (rule.value == value && !currentRule) {
                currentRule = rule;
            } else if (rule.value == value && currentRule && isImportant(s, value, def.cssText)) {
                rules.splice(currentRule.index, 0, currentRule);
                currentRule = rule;
            } else if (rule.value.length) {
                rules.push(rule)
            }
        }

        return {
            current: currentRule,
            overwritten: rules
        };

    } else {
        return false;
    }
}

如果发生继承,我们沿着 DOM 节点查找使用此辅助函数定义 CSS 规则的元素并获取其样式:

function getInherited(element, s, value) {
    while (element.parentNode && window.getComputedStyle(element.parentNode)[s] == value) {
        element = element.parentNode;
    }

    if (element) {
        return getStyle(s, element).current;
    } else {
        return null;
    }
}

我们使用此辅助函数确定是否将 CSS 规则标记为重要:

function isImportant(s, style, text) {
    return new RegExp(s.replace(/([A-Z])/g, '-$1').toLowerCase() + ':\\s+' + style + '\\s+!important').test(text)
}

看看小提琴看看它的工作原理

于 2013-08-16T10:54:02.423 回答
2

这个片段可能对你有用,它在过去帮助了我,将它应用到你的一个 CSS 文件中,你将能够通过查找元素 CSS 的特定位置来查看其他类/id 规则覆盖的对象声明是,并通过跟踪他们的父母。我的猜测是您在继承方面遇到问题。

* { outline: 2px dotted red }
* * { outline: 2px dotted green }
* * * { outline: 2px dotted orange }
* * * * { outline: 2px dotted blue }
* * * * * { outline: 1px solid red }
* * * * * * { outline: 1px solid green }
* * * * * * * { outline: 1px solid orange }
* * * * * * * * { outline: 1px solid blue }

或者,您可以为它们添加一个 :hover 属性,这会使导航更容易一些,但该片段的基本原理是向您展示元素的嵌套,并且可以帮助您确定 CSS 中的问题所在是

于 2012-06-06T15:37:04.337 回答
0

您必须解析链接到页面的 CSS 文件才能确定正在使用的样式。您还必须确定可以使用哪些属性来定位 CSS 中的元素。这是您必须遵循的流程:

元素可以通过以下方式成为目标:标签、ID、类、伪类和继承

然后,您将拥有一个给定的元素,例如:

<a href="#" id="link" class="button">Woop</a>

默认情况下,该元素有几个与之关联的选择器。所有元素都可以继承父 CSS,因此您必须创建父元素的层次结构。以后的样式将优先。然后,您必须考虑标签a和任何也共享此选择器的父级,例如body a. 同样,您必须创建继承属性的层次结构。您将对类、属性和伪类重复此过程。一旦你为元素编译了你的树列表,你就可以解析 CSS 文档以获得适当的样式。

这绝对是一项艰巨的任务,重新发明轮子没有任何意义。我的建议是查看已经这样做的开源项目。WebKit是一个已经构建了这个系统的开源项目。考虑使用他们的实现作为起点并从那里进行更改。

于 2013-08-12T19:40:32.397 回答