【问题标题】:CSS Specificity CounterCSS 特异性计数器
【发布时间】:2021-07-11 23:38:06
【问题描述】:

所以 CSS 特性 rules 规定 id 是最强大的,然后是类,然后是标签名称,然后是 *。

所以#id > .class > div > *

如果我提供一串 CSS 选择器,我要做的是为每个选择器获得一个“评级”。

假设我有一个特异性数组 = [#id, .class, tagname]

span 应该返回 [0, 0, 1]

body p 应该返回 [0, 0, 2]

.red .orange 应该返回 [0, 2, 0]

menu .item #checkout.active 应该返回 [1, 2, 1]

我试过这段代码,但肯定有问题:

function compare(a) {
    const comparisonOperators = ["#", ".", " "];
    const aRating = [];

    for (let x = 0; x < comparisonOperators.length; x++) {
        aRating[x] = a.includes(comparisonOperators[x])
            ? a.split(comparisonOperators[x]).filter((x) => x).length
            : 0;
    }

    console.log(aRating);
}

compare("menu .item #checkout.active");
// returns [2,3,3]

对此有什么想法吗?

【问题讨论】:

  • 计数准确。当你在'#'上拆分时,你有两个元素'menu .item'和'checkout.active'当你在'.'上拆分时你有三个元素'menu','item @checkout'和'active'当你在“”上拆分时,你也有三个元素“menu”,“.item”和“#checkout.active”

标签: javascript css-selectors css-specificity


【解决方案1】:

我采取了与您不同的方法来解决这个问题。

function compare(a) {
    var items = a.split([' ']);
    var aRating = [0,0,0];
    items.forEach(function(i) {
        //case 1
        if(i.split('#').length > 1) {
            aRating[0] = aRating[0] + (i.split('#').length - 1)
        }
        //case 2
        if(i.split('.').length > 1) {
            aRating[1] = aRating[1] + (i.split('.').length - 1)
        }
        //case 3
        if(!i.startsWith('#') && !i.startsWith('.')) { 
            aRating[2] = aRating[2] + 1
        }
        
    });
    console.log(aRating);
}

最初,我根据空格分割字符串。这给出了要检查的元素总数。然后,我循环遍历该数组中的每个项目,以确定并计算选择器的数量。

在情况 1 中,如果项目包含 ID,则其长度将大于 1。例如,#myId。如果我根据# 拆分它,那么我将在一个数组中得到 2 个项目。我正在使用它来确定它是否包含ID。在这种情况下,这是真的,所以我将 aRating 数组加 1。如果它不是 ID,那么它的长度将始终为 1,因为它不能被拆分。

同样的逻辑也适用于 css class 的情况 2。

案例 3 略有不同。如果字符串不是以# 或'.' 开头,那么它必须是标记名。

【讨论】:

    猜你喜欢
    • 2010-12-28
    • 2012-08-04
    • 1970-01-01
    • 2013-03-30
    • 2013-04-20
    • 2018-09-17
    • 2013-09-26
    • 1970-01-01
    • 2012-01-10
    相关资源
    最近更新 更多