【问题标题】:Is there an JS library that orders CSS selector texts according to specificity? [duplicate]是否有根据特异性对 CSS 选择器文本进行排序的 JS 库? [复制]
【发布时间】:2012-06-24 21:28:12
【问题描述】:

可能重复:
Sorting a set of CSS selectors on the basis of specificity

我需要一个 JS 库,将 CSS 选择器文本从最具体的选择器文本排序到不太具体的选择器文本,其中的特异性根据 W3C 指定

如果那里没有任何库,我可以简单地使用 JS 或 jQuery 编写它吗?

CSS 选择器文本可以是div#body .text

【问题讨论】:

  • 究竟什么是'specificty'
  • @RokoC.Buljan,我是defined by spec
  • Woho87,不清楚您在寻找什么 - 您是否想要一个调试工具,它会向您显示应用于特定元素的所有规则列表,按从最到的顺序排列最不具体?还是完全不同的东西? (另外,我将拼写从“specificity”固定为“specificity”。)
  • 你能解释一下你到底想要什么吗?恐怕如果没有这些信息,这个问题就会被关闭。
  • 我不需要任何调试工具。我正在创建一个调试工具:) 我只需要一个库,它将选择器文本从最具体的选择器文本排序到不太具体的选择器文本,其中的特异性是根据w3.org/TR/CSS21/cascade.html#specificity

标签: javascript jquery css css-selectors css-specificity


【解决方案1】:

在您问题的 cmets 中,josh3736 链接 the W3C specification for determining specificity。如果您倾向于自己编写这样的库(我鼓励这样做,如果没有其他原因,只是为了了解更多信息),他们的方法似乎是一个很好的参考。

选择器的特异性计算如下:

  • 如果声明来自,则计数 1 是“样式”属性而不是带有选择器的规则,否则为 0 (= a) (在 HTML 中,元素的“样式”属性的值是样式表规则。这些规则具有没有选择器,因此 a=1、b=0、c=0 和 d=0。)
  • 统计选择器中 ID 属性的数量 (= b)
  • 统计选择器中其他属性和伪类的数量 (= c)
  • 统计选择器中元素名和伪元素的个数(=d)

特异性仅基于选择器的形式。特别是,“[id=p33]”形式的选择器被视为属性选择器(a=0,b=0,c=1,d=0),即使 id 属性被定义为“ID " 在源文档的 DTD 中。

连接四个数字 a-b-c-d(在具有大基数的数字系统中)给出了特异性。

【讨论】:

  • 我自己可能正在写这篇文章。但我需要确保其他人还没有写它:)
【解决方案2】:

我想我会试一试。随意使用、修改(或修复)您认为合适的代码。我不能保证它是正确的,但是他们在 w3c 规范中给出的例子都产生了相同的结果。

function specificity(selector, isStyleAttribute) {

    selector = selector || "";
    function numMatches(regex) {
        return (selector.match(regex)||[]).length;
    }

    var numClasses = numMatches(/\.[\w-_]+\b/g);
    var numIds = numMatches(/#[\w-_]+\b/g);
    var numNamesInBraces = 0;
    var namesInBraces = selector.match(/\[[^\]]*\b[\w-_]+\b[^\]]*\]/g) || [];
    for (var idx = 0; idx < namesInBraces.length; ++idx) {
        numNamesInBraces += (namesInBraces[idx].match(/\b[\w-_]+\b/g)||[]).length;
    }

    var results = [0,0,0,0];
    results[0] = isStyleAttribute ? 1 : 0;
    results[1] = numIds;
    results[2] = numMatches(/\[[^\]]+\]/g) + numClasses;
    results[3] = numMatches(/\b[\w-_]+\b/g) - numIds - numClasses - numNamesInBraces;
    return results.join(',');

}

如果你想用它对数组进行排序,可以这样使用:

selectors.sort(function(a,b) { return specificity(a) > specificity(b); });

【讨论】:

  • 内联样式没有选择器——您必须不传递任何内容作为第一个参数并完全跳过所有这些检查。在我链接到的重复问题中,我提供了一个涵盖大部分部分的框架,但是我可能最终会实现与我最初计划的完全不同的东西......
  • 如果您愿意,我可以将您的答案合并到另一个问题中。
猜你喜欢
  • 2011-07-06
  • 2012-05-25
  • 1970-01-01
  • 2020-07-20
  • 2012-08-25
  • 2018-12-10
  • 2013-12-11
相关资源
最近更新 更多