regex - How to remove all pseudo selectors from a CSS selector string using Javascript? - Stack Overflow

For a script I'm doing I need to verify a CSS selector exists in the DOM. I'm wondering how t

For a script I'm doing I need to verify a CSS selector exists in the DOM. I'm wondering how to handle multiple :pseudo selectors with a generic rule.

Something like this is simple:

var selector = "div.foo div.bar:active"

which could be handled by

selector.split(":").shift(); // > div.foo div.bar

but when I have multiple selectors, I'm don't know how I could remove them. Something like this:

var selector = "div.foo:hover div.bar:after"

Question:
How would I remove all CSS pseudo selectors (":something") from a string?

For a script I'm doing I need to verify a CSS selector exists in the DOM. I'm wondering how to handle multiple :pseudo selectors with a generic rule.

Something like this is simple:

var selector = "div.foo div.bar:active"

which could be handled by

selector.split(":").shift(); // > div.foo div.bar

but when I have multiple selectors, I'm don't know how I could remove them. Something like this:

var selector = "div.foo:hover div.bar:after"

Question:
How would I remove all CSS pseudo selectors (":something") from a string?

Share Improve this question edited Aug 3, 2014 at 12:27 BoltClock 725k165 gold badges1.4k silver badges1.4k bronze badges asked Aug 3, 2014 at 12:21 frequentfrequent 28.6k61 gold badges187 silver badges336 bronze badges 1
  • so you want only div.foo string. – Avinash Raj Commented Aug 3, 2014 at 12:24
Add a ment  | 

2 Answers 2

Reset to default 7

You can remove them with a regular expression and replace:

selector = selector.replace(/::?[^ ,:.]+/g, '');

(The ::? means one or two colons [you could also write it as :{1,2}], to handle ::after and such; full regex explanation.)

That works for most situations, but if you have really plex pseudos with nested pseudos like foo.bar:not(.baz:active) (will be in CSS4), you'll need an actual CSS selector parser to handle them properly. While you could probably build a regex alternation that would handle one bit of nesting, in theory there can be multiple nesting, which is where a parser es in.

But note that some of these pseudos do affect which element is chosen, such as :nth-child, so if your goal is to see if a matching element is in the DOM, you wouldn't want to remove those. So you might want to take the fairly pragmatic approach of listing the ones that you want to remove in a series of alternations, e.g.:

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

There aren't all that many, and it eliminates the chance of removing important structural ones line :nth-child.

Removing all pseudo-selectors will not solve your problem.

Take this example:

p:first-child {}

<div>
    <div></div>
    <p></p>
</div>

Since the paragraph is not the first child (and won't be unless the DOM changes), removing :first-child from the selector will give you a false positive match.

You need to remove only the pseudo-classes which are conditional upon things like mouse or keyboard interaction and the psuedo-elements. Then you need to special case :link and :visited so that the match anchors that are links and not ones that aren't (replacing them with an attribute selector of [href] is a slightly naïve approach, but should be good enough for all practical purposes).

You'll also need to make a decision for :enabled and :disabled. They aren't going to be changed by user interaction, but if you plan to toggle them with JS then you'll probably want to remove them.

Since there are a lot of conditions here, I'd write a function for it rather than attempting a simple regex.

发布者:admin,转转请注明出处:http://www.yc00.com/questions/1745235039a4617851.html

相关推荐

发表回复

评论列表(0条)

  • 暂无评论

联系我们

400-800-8888

在线咨询: QQ交谈

邮件:admin@example.com

工作时间:周一至周五,9:30-18:30,节假日休息

关注微信