在具有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",
]
这方面的任何指示都会非常有帮助。
答案 0 :(得分:4)
首先,让我们坚持一个涉及标签名称,类名和ID的狭窄选择器类,没有像E > F
或E + 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