按顺序排列简单的选择器

Posted

技术标签:

【中文标题】按顺序排列简单的选择器【英文标题】:Ordering simple selectors in a sequence 【发布时间】:2015-02-17 21:04:42 【问题描述】:

这只是一个概念性问题,涉及良好实践。


问题很简单。是否有任何“正确”的方式来订购 jQuery/CSS 选择器的各个部分?例如,假设我有一个具有以下属性的元素:

<div class="red green blue" id="someDiv" anAttr="something">

为了更好的衡量,让我们在悬停时也将其作为目标。


下面的选择器有什么区别吗?:

div.red.green.blue#someDiv[anAttr='something']:hover
div#someDiv.red.green.blue[anAttr='something']:hover
div.red#someDiv[anAttr='something']:hover.blue.green
div[anAttr='something'].blue:hover#someDiv.red.green

意思是,目标的顺序真的很重要吗?或者我可以把它们按我想要的顺序排列吗?

根据这个JSFiddle,他们都在技术上工作。

【问题讨论】:

你喜欢哪种方式都可以。 好奇:它们都有效吗?有些语法看起来很奇怪。从语义上讲,我更喜欢从id 开始,然后是class,然后是其他attributes,然后是attribute values,最后是状态(即:hover:checked 等) 这可能对你有帮助:Specifics on CSS Specificity 另一个好来源:CSS Specificity: Things You Should Know @ochi 我可以确认:They all work 【参考方案1】:

5.2 选择器语法

一个简单的选择器要么是类型选择器,要么是通用选择器 紧随其后的是零个或多个属性选择器,ID 选择器或伪类,以任意顺序。简单的选择器 如果其所有组件都匹配,则匹配。

注意:这里在 CSS 2.1 中使用的术语与现在的不同 在 CSS3 中使用。例如,“简单选择器”指的是较小的 CSS3 中的选择器的一部分,而不是 CSS 2.1 中的选择器。查看 CSS3 选择器 模块 [CSS3SEL]。

选择器是一个或多个简单选择器的链,由 组合器。组合符是:空格、“>”和“+”。空白空间 可能出现在组合器和它周围的简单选择器之间。

文档树中匹配选择器的元素被称为 选择器的主题。由一个简单的选择器组成 选择器匹配任何满足其要求的元素。前置一个 链的简单选择器和组合器强加了额外的匹配 约束,所以选择器的主题总是 匹配最后一个简单选择器的元素。

一个伪元素可以附加到最后一个简单的选择器 链,在这种情况下,样式信息适用于 每个主题。

发件人:w3.org

【讨论】:

【参考方案2】:

排序可以影响 jQuery 选择器的速度。我为它做了一个jsPerf test,结果证明只使用 ID 是最快的(并不奇怪),而首先使用属性选择器是最慢的,稍微慢一点。其他的都差不多。

请注意,我必须删除 jQuery 的 :hover 选择器,因为这纯粹是一个 CSS 东西 AFAIK。

【讨论】:

非常有趣。那么,简洁比具体更好 ??!?至少在使用 ID 的情况下。 好吧,单独使用 ID 短路到document.getElementById,这比使用document.querySelectorAll 快​​得多。按类名和document.getElementsByClassName 选择也是如此。此外,jQuery 可以理解:hover,如果它是一个最终将被传递给document.querySelectorAll 的选择器。但是,它几乎永远不会有用。【参考方案3】:

请注意,正如 emmanuel 回答中的引文所述,CSS2.1 与 the current level 3 standard 的术语略有不同,因此我认为 CSS2.1 定义已过时。语法几乎保持不变,但术语更加明确:简单选择器现在总是引用每个现在称为简单选择器序列的任何一个组件,或者更好的是,复合选择器 .

这里是来自 3 级标准的相同引用,只是相关的部分:

4。选择器语法

一个简单选择器序列是一个不被组合符分隔的简单选择器链。它总是以类型选择器或通用选择器开头。序列中不允许有其他类型选择器或通用选择器。

简单选择器可以是类型选择器、通用选择器、属性选择器、类选择器、ID 选择器或伪类。

与 CSS2.1 不同,该规范没有明确使用“以任何顺序”这一​​短语,但很容易暗示它只声明了类型/通用选择器的例外情况。据我所知,此异常的唯一原因是类型选择器没有任何特殊符号,如果它出现在复合选择器中的其他任何地方,则无法与另一个简单选择器区分开来。通用选择器尽管用星号表示,但实际上仅表示“任何类型的元素”——如果你愿意,它是通配符类型选择器,因此它遵循与类型选择器相同的规则。

还可以查看the upcoming standard,它看到了更显着的变化(并定义了术语“复合选择器”)。

我有几点要补充:

现在可能广为人知的是,大多数浏览器使用的本机选择器引擎评估 right-to-left order 中的选择器。有一种误解认为这适用于简单选择器级别。 它没有。 不严格,反正。针对一些常见情况进行了各种优化,例如 ID 选择器的存在、类选择器的存在、动态伪类的存在等等。这些优化几乎总是发生,无论它们在复合选择器中的位置如何。没有人会先看最右边的简单选择器,当它真的是最重要的类型或 ID 选择器时,尤其是当您考虑到大多数作者将 ID 放在靠近开头的某个位置,而类型选择器只能 出现在开头。

在我对this question 的回答中,关于选择器引擎的简单选择器排序主题,我通过示例进行了更详细的说明。

暗示 jQuery 的选择器引擎 Sizzle 遵循相同的规则,但请记住,与内置于布局引擎中的选择器引擎一样,这只是标准的一个实现。实现的整个本质是,每个人做的事情有些相似,有些则完全不同,因此无法在极其精细的级别上对性能进行限定。

然而,一个序列中的简单选择器越少,选择器引擎在评估选择器时要做的工作就越少,这几乎是常识。您应该只根据需要进行具体说明,仅此而已。例如,您可以使用类选择器或伪类来限制 ID 选择器的上下文,但几乎不需要超出此范围。

众所周知,jQuery 将单独的 ID 选择器、类选择器和类型选择器分别优化为 document.getElementById()document.getElementsByClassName()document.getElementsByTagName()。您可以使用任何其他选择器对它们进行限定,它仍然可以工作,但是作为权衡,您会失去这些优化路径。原生选择器引擎中存在类似的优化,但就相似性而言,无论如何对作者来说都是重要的。

说到jQuery,因为你的问题被标记为jquery-selectorscss-selectors,请注意jQuery不支持某些动态伪类,例如:hover。但是,基本原理保持不变。 (正如评论中提到的,如果传递给document.querySelectorAll(),它可以检测到当前为:hover 的元素,但由于显而易见的原因,这几乎没有用处。)

所以,简而言之:在订购简单选择器时不要担心性能。性能上的任何偏差通常都是无关紧要的,只有最明显的例外。除了上面提到的之外,该语法不施加任何其他限制。您所要做的就是避免资格过高,并保持一致。

例如,这是我对简单选择器的排序方式——语法允许我选择我喜欢的任何顺序,这正是我觉得合适的:

a#id[attr=val].class1.class2:nth-child(n):link:hover

【讨论】:

【参考方案4】:

放置它们的顺序无关紧要。重要的是你的 CSS 类的内容。

您需要确保其中一个 css 类没有设置会覆盖另一个 css 类的样式的属性。

在下面的示例中,绿色类将覆盖红色类,使您的 div 的文本颜色为绿色。

示例 CSS:

 .red

   /* set text color to red */
   color:red;

 

 .green

  /* set text color to red */
  color:green;

 

【讨论】:

以上是关于按顺序排列简单的选择器的主要内容,如果未能解决你的问题,请参考以下文章

使用LocalStorage按字母顺序排列内容列表

选择器

Azure 数据资源管理器获取不同的值并按顺序排列

css选择器都有哪些?各种选择器优先级大小顺序

使用 Core Data 时如何重新排列部分

每日一小练——按字典顺序列出全部排列