检测样式是否为用户样式

Detecting if a style is a user style

本文关键字:样式 用户 是否 检测      更新时间:2023-09-26

调用window.getComputedStyle后,如何判断样式是否来自页面本身(而不是来自浏览器(?我对纯javascript感兴趣,尽管我会满足于在附加组件上下文中运行的解决方案。

你将很难弄清楚getComputedStyle给你的规则来自哪里。请注意,MaxArt 提供的代码不是一个完整的解决方案 - 也有继承的样式,因此必须为父节点重复所有内容。更简单的方法是使用 inIDOMUtils.getCSSStyleRules() ,按照以下思路:

function isPageStyle(styleSheet)
{
  if (styleSheet.ownerNode)
    return true;
  if (styleSheet.ownerRule instanceof Components.interfaces.nsIDOMCSSImportRule)
    return isPageStyle(styleSheet.parentStyleSheet);
  return false;
}
var domUtils = Components.classes["@mozilla.org/inspector/dom-utils;1"]
                         .getService(Components.interfaces.inIDOMUtils);
var rules = domUtils.getCSSStyleRules(element);
for (var i = 0; i < rules.Count(); i++)
{
  var rule = rules.GetElementAt(i);
  if (isPageStyle(rule.parentStyleSheet))
    alert(rule.cssText);
}

您还必须为父节点执行此操作。有关完整的示例,您可以查看Firefox中检查器功能的实现(我的回答中的isPageStyle功能无耻地从这里"借用"(。

除非你想解析文档中的每个样式表,否则你不能。如果您对默认情况下每个浏览器应用于元素的样式有疑问,您可以依靠类似 重置 CSS 的东西。

如果你想解析样式表,无论如何,你可以做这样的事情:

function isDefaultStyle(element, property) {
    if (element.style[property]) return false;
    for (var i = 0; i < document.styleSheets.length; i++) {
        for (var j = 0, r; j < document.styleSheets[i].cssRules.length; j++) {
            r = document.styleSheets[i].cssRules[j];
            if (element.matchesSelector(r.selectorText) && r[property]) return false;
        }
    }
    return true;
}

matchesSelector 是一种元素方法,实际上没有任何浏览器支持,它实际上支持命名空间函数,如 webkitMatchesSelectormozMatchesSelectoroMatchesSelector 甚至msMatchesSelector (IE9+(。可悲的是,对于IE8,您必须模拟它,我找不到比检查元素是否包含在document.querySelectorAll(r.selectorText)中更好的方法,这对于大型DOM树来说可能非常慢。

在最后一种情况下,您显然也必须使用 rules 而不是 cssRules .