如何检测被覆盖的 CSS 属性?

2024-05-16

I can get all css properties for an element with document.stylesheets but some of those are not active because those properties are overwritten. In firebug (chrome developer tools also has this feature), if there's an overwritten css property, you will see something like that: enter image description here

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


在 webkit 中,你可以使用getMatchedCSSRules实现你想要的。它按照浏览器应用的继承顺序返回一个 CSS 规则集,并且它是 webkit 检查器使用的 https://bugs.webkit.org/show_bug.cgi?id=79653前一段时间。对于像 Firefox 这样基于 Gecko 的浏览器,似乎有一个可用的 polyfillhere https://gist.github.com/ydaniv/3033012虽然我还没有测试过。

一个基本的、可行的解决方案

以下代码也可以作为小提琴使用 http://jsfiddle.net/UXJHt/

Because getMatchedCSSRules 仅适用于内联样式表 http://code.google.com/p/chromium/issues/detail?id=69626,您首先必须内联链接的样式表:

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规则,最多 1 个!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)
}

看看小提琴,看看它是否工作 http://jsfiddle.net/UXJHt/

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

如何检测被覆盖的 CSS 属性? 的相关文章

随机推荐

  • WCF 服务参考支持文件未更新

    我有一个 VS 2010 解决方案 其中包含一个 WCF 服务项目和一个单元测试项目 单元测试项目有一个对WCF服务的服务引用 WCF 服务项目的 Web config 将许多绑定属性设置为非默认值 网络配置 特别注意maxBufferSi
  • 从 sockaddr_storage 检索 ip 和端口

    我有一个sockaddr storage包含远程主机的 ipv4 地址和端口 我没见过这些struct但之前我不知道如何将它转换成struct我可以直接检索IP地址和端口号 我尝试过谷歌搜索struct但还没有发现任何东西 关于如何执行此操
  • Notification.Builder 中 setGroup() 的用途是什么?

    我对目标的理解有些困难setGroup http developer android com reference android app Notification Builder html setGroup java lang String
  • 如何修复“iptables:没有该名称的链/目标/匹配”?

    我在我的 Linux 嵌入式系统上构建并安装了 iptables 如果我列出所有规则 则一切正常 iptables list Chain INPUT policy ACCEPT target prot opt source destinat
  • 如何限制firebase中的字符串长度

    我在 firebase 数据库中工作 我需要限制字符串字段的长度 我怎么做 到该字段的路径是 Col1 doc1 描述 也就是说 从集合 col1 开始 然后进入 doc1 然后对于 doc1 下的所有集合以及该集合下的所有文档 描述字段需
  • 如何在 Razor 中设置数字编辑器的最小值、最大值和默认值

    我有一个 int 值 我想将其渲染为数字 up down 其 id 为 Quantity 因此我在 razor 中执行以下操作 div class field label Html LabelFor m gt model Quantity
  • 使用 Java 将摩尔斯电码转换为英文文本

    我最近有一项任务 将英语转换为摩尔斯电码 并将摩尔斯电码转换为英语 输入莫尔斯电码时 我的老师希望各个字母之间用 1 个空格分隔 单词之间用 分隔 例如 是 成为 我能够完美地将英语转换为莫尔斯电码 但我对莫尔斯电码转换为英语感到不知所措
  • 使用 Spring 和 Angular 进行 Html5 路由

    我正在尝试使用 Spring boot 和 Angular 1 5 实现 HTML5 路由 如下本文 https spring io blog 2015 05 13 modularizing the client angular js an
  • ajax 会增加还是降低安全性?

    我正在创建一个网站 到目前为止它是纯 PHP 的 我在想 既然很少有人没有启用 JavaScript 我想知道为什么 也许我应该将我的网站创建为一个完全 PHP 的网站 而不使用任何 AJAX 难道是我想错了 可以肯定的是 如果我实施一些
  • GPU的编程语言有哪些

    我读过一篇文章 指出 GPU 是超级计算的未来 我想知道在GPU上编程使用什么编程语言 OpenCL 是开放式跨平台解决方案 可在 GPU 和 CPU 上运行 另一个是 NVIDIA 为其 GPU 构建的 CUDA HLSL Cg 等少数几
  • Mesibo 通话 UI 未更新

    我正在尝试更改 Mesibo Call UI 的配置 但它并没有改变 我尝试如下 MesiboCallConfig mesiboCallConfig new MesiboCallConfig mesiboCallConfig backgro
  • Facebook 分享自定义消息

    项目网站上有一个测验 您可以回答一些问题 然后根据答案得出结果 结果有时会有所不同 但客户要求结果 自定义消息 应该能够在 Facebook 上共享 我想做的就是通过自定义消息分享测验的网址 即 我在有关历史的测验中回答了 10 个问题中的
  • 如何在 Laravel Mix 中将公共路径更改为包含下划线的路径?

    Laravel 5 4 中引入了 Mix 来编译资产并维护资产管道 Mix 默认为您的公共目录被命名public 在许多情况下 包括我的 我的公共目录被称为其他名称 就我而言 是public html 如何更改资源编译到的公共目录 我尝试过
  • Entity Framework Core 中的两个外键

    我在使用 Entity Framework Core 创建数据库时使用代码优先方法 我想创建两个指向同一个表的外键 我的示例显示用户表将保存用户 ID 消息表将保存接收者 ID 和发送者 ID 这意味着两个值必须指向同一个表 用户代码 pu
  • 无法删除 Cloud Composer 环境

    我正在尝试删除我只是为了尝试而创建的 Cloud Composer 环境 我收到以下错误 此环境上的 DELETE 操作在 9 小时前失败 原因是 以下错误消息 为防止删除而放置的留置权 由 serviceconsumermanagemen
  • 如何从一维数组和静态字符串创建对象

    我想要一个像 var obj ABC name true dob true CDE name true dob true EFG name true dob true CBA name true dob true XYZ name true
  • “即发即忘”异步委托的正确方法

    就我而言 我对异步委托这个话题很生疏 如果我想以 一劳永逸 的方式异步调用一个方法 这是一种合适的方法吗 Action action DoSomething action BeginInvoke action EndInvoke null
  • 页面在 Google Adwords 转化跟踪上重定向

    我有一个表单 人们可以在其中提交数据 然后使用 ajax 将数据发送到服务器 我已将其设置为 Google Adwords 中的转化 下面是我使用过的代码 问题是 当用户提交表单时 在收到响应后 它会重定向回我给出的 URL 我不想重定向
  • 向resource.resx添加新字符串不会反映到Designer.cs中

    我将两个新字符串添加到我们的resource resx中 但这些新添加的资源 字符串 没有反映到自动生成的Designer cs文件中 我已经重建了该项目 并尝试了 clean build 该项目 但没有运气 我有其他资源文件来支持各种国际
  • 如何检测被覆盖的 CSS 属性?

    I can get all css properties for an element with document stylesheets but some of those are not active because those pro