Reputation: 18680
From page=$("#page")
I want to get all the specified SVGs but not the subsequent inner ones.
<div id="page">
<div ...>
<svg> /* THIS ONE */
<rect ...>
<circle ...>
<svg> /* NOT THIS ONE */
<foo> ... </foo>
</svg>
</svg>
</div>
<div ...>
<div ...>
<svg> /* THIS ONE */
<rect ...>
<circle ...>
<svg> /* NOT THIS ONE */
<foo> ... </foo>
</svg>
</svg>
</div>
</div>
</div>
EDIT I've updated the markup to clearly specify what I mean.
One solution is to use :not(svg svg)
which i find ugly and performance heavy.
Upvotes: 2
Views: 192
Reputation: 196002
After updated question
The only solutions are
$('#page svg:not(:has(svg))');
and your own
$('#page svg:not(svg svg)');
Performance-wise (check out the test) they are about the same with no clear winner
original answer
For the particular example
$('#page > svg:first')
or
$('#page svg:first')
will suffice.
But consider the following case
<div id="page">
<div>
<p>
<svg id="svg-1"></svg>
</p>
<svg id="svg-2"></svg>
</div>
</div>
Is this case possible (both svgs wrapped in something else) ? and if so, do you want #svg-2
?
This case is not handled by the >
version at all, and the$('#page svg:first')
version will return the #svg-1
Upvotes: 3
Reputation: 168695
If you know it's always going to have a <div>
parent, you could do this (which avoids having to know how many elements are between #page
and div
):
#page div>svg
Upvotes: 1
Reputation: 270
You could use the following:
$(page).children(svg).first()
Which will get you the first svg, in this case the outer most one, but might also still be performance heavy if that is part of your concern.
Upvotes: 1