如何生成所有可能的CSS 2选择器组合? [英] How to Generate All Possible CSS 2 Selector Combinations?

查看:92
本文介绍了如何生成所有可能的CSS 2选择器组合?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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



例如:
对于以下MarkUp

  ;!DOCTYPE html PUBLIC -  // W3C // DTD XHTML 1.0 Transitional // ENhttp://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd\"> 
< html xmlns =http://www.w3.org/1999/xhtmlxml:lang =en>
< head>
< meta http-equiv =Content-Typecontent =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 - > 在上面的标记中作为方法的参数,它返回所有可能的CSS 2数组形式的Argument的选择器组合。可以将一个可选参数添加到将定义CSS 2选择器嵌套的最大深度的方法。如果此参数设置为false,则应返回所有可能的组合(如果设置为false,则为性能hogger)



示例输出:

  [
.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> F E + F 。让我们也禁止类名称的组合( .class1.class2.class3 ),否则一个具有10个类名的元素将会单独生成4百万个选择器。



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



给定一个DOM元素grab的引用它的标签名称, ID和类名。计算如上所述的所有可能的简单选择器。让我们称之为A1。将层次结构向上一级移动到其父级,计算该父级元素的所有简单选择器 - 即集合A2。继续,直到你到达html元素 - 集合Am。现在你将有一个列表,包括m个项目,每个项目是一组简单的选择器。



现在选择一些这些集合,并找到他们的笛卡尔积。说,m = 5.你可以选择多少套?集合A1始终存在,但其他是可选的。对于他们中的每一个,你或不是选择它。这就像二进制数:

  0000 // 0,A1 
0001 // 1,A1 x A2 $ b b 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 //内部div
div span //外部div
div div span

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






UPDATE



所以,我决定多玩一下,写下程序,示例生成: http://pastie.org/1616164


What would be the best way to generate all possible CSS 2 Selector Combinations for a DOM element in context with the current state of the document?

Eg: For the following 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>

A JS/jQuery Method such that the <!--ARGUMENT ELEMENT--> in the above markup is given as an argument to the method it returns all possible CSS 2 Selector combinations for the Argument in form of an array. An optional parameter can be added to the method which will define the maximum depth of CSS 2 Selector Nesting. If this parameter is set to false it should return all possible combinations (Will be a performance hogger if set to false)

Example Output:

[
 ".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",
]

Any pointers in this regard will be extremely helpful.

解决方案

First, let's stick to a narrow class of selectors involving tag names, class names and IDs, nothing fancy like E > F or E + F. Let's also disallow combinations of class names (.class1.class2.class3), otherwise a single element with 10 class names would generate 4 million selectors alone.

Each of our full selectors consists of simple selectors separated by spaces. Every simple selector is a combination of tag{0,1}id{0,1}class{0,n} - i.e. each element has exactly one tag, at most one ID, and it can have an arbitrary number of class names. That gives us the upper limit of 2 * 2 * (n + 1) simple selectors for a single element.

Given a reference to a DOM element grab it's tag name, ID and class names. Calculate all possible simple selectors as described above. Lets call this set A1. Move one step up the hierarchy to it's parent, calculate all simple selectors for that parent element - that'll be the set A2. Continue until you reach the html element - the set Am. Now you'll have a list, consisting of m items, each item is a set of simple selectors.

Now pick some of these sets and find their cartesian product. Say, m = 5. How many sets can you pick? The set A1 is always present, but others are optional. For each one of them you either pick it or not. That's like binary numbers:

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
...

That means you'll have 2^(m-1) cartesian products. You can now convert them to strings. The last step is to remove duplicates, consider this example:

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

Our calculations will yield this list:

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

Those two divs yield duplicate selectors. Remove those and the job is done. All the steps are very simple algorithmically. I'm sure you can figure them out, but if you get stuck somewhere or need further clarification feel free to ask me in the comments.


UPDATE

So, I decided to play with it a bit more and wrote the program, here's the list of selectors your example generates: http://pastie.org/1616164

这篇关于如何生成所有可能的CSS 2选择器组合?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆