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?
-
so you want only
div.foo
string. – Avinash Raj Commented Aug 3, 2014 at 12:24
2 Answers
Reset to default 7You 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条)