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

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

例如:对于以下MarkUp

        
  • a
  • b
  • c

一个JS / jQuery方法,使得上面标记中的作为方法的参数给出,它以数组的forms返回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", ] 

在这方面的任何指针都将非常有帮助。

首先,让我们坚持一个狭窄的选择器类,涉及标签名称,类名和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)个笛卡尔积。 您现在可以将它们转换为字符串。 最后一步是删除重复项,请考虑以下示例:

 

我们的计算将产生以下列表:

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

这两个div产生重复的选择器。 删除那些,工作完成。 所有步骤在算法上都非常简单。 我相信你可以把它们搞清楚,但是如果你被困在某个地方或需要进一步澄清,请随时在评论中问我。


UPDATE

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