如何生成所有可能的CSS 2选择器组合?

时间:2011-02-27 19:16:04

标签: javascript jquery dom css-selectors

在具有document当前状态的上下文中为DOM元素生成所有可能的CSS 2 Selector组合的最佳方法是什么?

例如:     对于以下MarkUp

<!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方法,使得上述标记中的<!--ARGUMENT ELEMENT-->作为方法的参数给出,它以数组的形式返回Argument的所有可能的CSS 2选择器组合。可以在方法中添加一个可选参数,该参数将定义CSS 2 Selector Nesting的最大深度。如果此参数设置为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",
]

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

1 个答案:

答案 0 :(得分:4)

首先,让我们坚持一个涉及标签名称,类名和ID的狭窄选择器类,没有像E > 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产生重复的选择器。删除那些,工作完成。 所有步骤在算法上都非常简单。我相信你可以把它们搞清楚,但如果你遇到困难或需要进一步澄清,请随时在评论中问我。


<强>更新

所以,我决定更多地使用它并编写程序,这是您的示例生成的选择器列表:http://pastie.org/1616164