【问题标题】:How to Generate All Possible CSS 2 Selector Combinations?如何生成所有可能的 CSS 2 选择器组合?
【发布时间】:2011-07-05 08:26:12
【问题描述】:

document 的当前状态下,为 DOM 元素生成所有可能的 CSS 2 选择器组合的最佳方法是什么?

例如: 对于以下标记

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">
<head>
  <meta http-equiv="Content-Type" content="text/html;charset=UTF-8" />
  <title></title>
</head>
<body>
  <div id="content">
    <ul>
      <li>a</li>
      <li>b</li>
      <li class="last-li">c</li> <!--ARGUMENT ELEMENT-->
    </ul>
  </div>
</body>
</html>

一种 JS/jQuery 方法,使得上述标记中的 &lt;!--ARGUMENT ELEMENT--&gt; 作为该方法的参数,它以数组的形式返回参数的所有可能的 CSS 2 选择器组合。可以将一个可选参数添加到定义 CSS 2 选择器嵌套的最大深度的方法中。如果此参数设置为 false,它应该返回所有可能的组合(如果设置为 false,将是性能消耗者)

示例输出:

[
 ".last-li",
 "li.last-li",
 "ul .last-li",
 "ul li.last-li",
 "div ul .last-li",
 "div ul li.last-li",
 "#content ul .last-li",
 "#content ul li.last-li",
 "div#content ul .last-li",
 "div#content ul li.last-li",
 "body div ul li.last-li",
 "body div ul .last-li",
 "body #content ul li.last-li",
 "body div#content ul .last-li",
 "body div#content ul li.last-li",
]

这方面的任何指示都会非常有帮助。

【问题讨论】:

  • 加入所有其他选择器,即使是最琐碎的文档也会生成大量可能的选择器。这肯定不是一个有用的练习吗?!
  • :root &gt; :last-child :only-child:not(ul) :not(:nth-last-child(2n+1)) ~ li 这样的东西怎么样?
  • @BoltClock 你可以无限链接:not。这不是一个明智的选择器,但它是一个有效的选择器。
  • @GeekTantra:那么你打算把引擎的所有可用资源都花在单独计算选择器上吗? 到底是为了什么?
  • @GeekTantra 我会重复其他人所说的话。您需要向我们说明您需要此列表的原因,以便我们可以将列表限制为合理的子集或建议替代解决方案。否则这将一事无成

标签: javascript jquery dom css-selectors


【解决方案1】:

首先,让我们坚持使用包含标签名称、类名称和 ID 的选择器类别,没有什么像 E &gt; FE + F 这样的花哨。让我们也禁止类名的组合 (.class1.class2.class3),否则具有 10 个类名的单个元素将生成 400 万个选择器。

我们的每个完整选择器都包含由空格分隔的简单选择器。每个简单的选择器都是tag{0,1}id{0,1}class{0,n} 的组合——即每个元素只有一个标签,最多一个ID,并且可以有任意数量的类名。这为我们提供了单个元素的 2 * 2 * (n + 1) 个简单选择器的上限。

给定一个对 DOM 元素的引用,获取它的标签名、ID 和类名。如上所述计算所有可能的简单选择器。让我们将此集合称为 A1。将层次结构向上移动到其父元素,计算该父元素的所有简单选择器 - 这将是集合 A2。继续直到到达 html 元素 - 集合 Am。现在您将拥有一个列表,由 m 个项目组成,每个项目都是一组简单的选择器。

现在选择其中一些集合并找到它们的笛卡尔积。比如说,m = 5。你能挑几组?集合 A1 始终存在,但其他是可选的。对于它们中的每一个,您要么选择它,要么不选择它。这就像二进制数:

0000 // 0, A1
0001 // 1, A1 x A2
0010 // 2, A1 x A3
0011 // 3, A1 x A2 x A3
0100 // 4, A1 x A4
...

这意味着您将有 2^(m-1) 个笛卡尔积。您现在可以将它们转换为字符串。最后一步是删除重复项,考虑这个例子:

<div>
  <div>
    <span></span>
  </div>
</div>

我们的计算将产生这个列表:

  span
  div span // inner div
  div span // outer div
  div div span

这两个 div 会产生重复的选择器。删除这些,工作就完成了。 所有步骤在算法上都非常简单。我相信您可以弄清楚它们,但是如果您在某个地方遇到困难或需要进一步说明,请随时在 cmets 中询问我。


更新

所以,我决定多尝试一下并编写程序,这是您的示例生成的选择器列表:http://pastie.org/1616164

【讨论】:

    猜你喜欢
    • 2018-01-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-01-07
    相关资源
    最近更新 更多