如何使用Javascript从CSS选择器字符串中删除所有伪选择器?

fre*_*ent 0 javascript regex string css-selectors pseudo-class

对于我正在做的脚本,我需要验证DOM中存在的CSS选择器.我想知道如何:pseudo使用通用规则处理多个选择器.

这样的事情很简单:

var selector = "div.foo div.bar:active"
Run Code Online (Sandbox Code Playgroud)

这可以通过

selector.split(":").shift(); // > div.foo div.bar
Run Code Online (Sandbox Code Playgroud)

但是当我有多个选择器时,我不知道如何删除它们.像这样的东西:

var selector = "div.foo:hover div.bar:after"
Run Code Online (Sandbox Code Playgroud)

问题:
如何":something"从字符串中删除所有CSS伪选择器()?

T.J*_*der 5

您可以使用正则表达式删除它们replace:

selector = selector.replace(/::?[^ ,:.]+/g, '');
Run Code Online (Sandbox Code Playgroud)

(::?意思是一两个冒号[你也可以把它写成:{1,2}],处理::after等等; 完整的正则表达式解释.)

这适用于大多数情况,但如果你有非常复杂的伪嵌入伪像foo.bar:not(.baz:active)(将在CSS4中),你需要一个真正的CSS选择器解析器来正确处理它们.虽然你很可能建立一个正则表达式的交替,将处理一个嵌套的比特,理论上可以有多个嵌套,这是其中一个解析器的用武之地.

但请注意,其中一些伪确实会影响选择哪个元素,例如:nth-child,如果您的目标是查看匹配元素是否在DOM中,则您不希望删除它们.因此,您可能希望采用相当务实的方法列出要在一系列替换中删除的那些,例如:

var toRemove = /:hover|:active|:before|:after|::?before|::?after|:and-so-on/g;
// ...
selector = selector.replace(toRemove, '');
Run Code Online (Sandbox Code Playgroud)

没有那么多,它消除了删除重要结构线的机会:nth-child.

  • 另外,我知道这只是一个例子,但有趣的是,虽然`foo.bar:not(.baz:active)`在撰写本文时目前不是有效的CSS,但它将在Selectors 4中.`:not( )``目前接受单独的伪类(`:not(:active)`),所以它仍然是你需要担心的事情. (2认同)