Reputation: 12259
Take the following, schematic html-code:
<div>
<span id='1' cust-attr='' />
<span id='2' />
<span id='3' cust-attr='Foo' />
</div>
Now I am looking for a selector finding all span
s which either do not have an attribute "cust-attr" or whose "cust-attr" value is empty.
In this case, this would be the 1 and 2.
I tried the following selectors with the following results:
span[cust-attr!=]
selects 2 and 3span[cust-attr='']
only selects 1span:not([cust-attr])
selects 2span(:not([cust-attr]),[cust-attr=''])
selects all threespan([cust-attr=''],:not([cust-attr]))
selects 1However, I did not find one selecting only 1 and 2.
Do you know a possibility?
Note that I want to avoid:
span:not([cust-attr]),span[cust-attr='']
as "span" is in reality a more complex expression.
Upvotes: 10
Views: 13385
Reputation: 106
:where()
or :is()
Like this:
span:where([cust-attr=""], :not([cust-attr]))
or this:
span:is([cust-attr=""], :not([cust-attr]))
:where()
vs :is()
are the specificityThe difference between :where() and :is() is that :where() always has 0 specificity, whereas :is() takes on the specificity of the most specific selector in its arguments.
Using :where()
will not increase the specificity. Using :is()
will use the highest selector specificity.
specificity:
id
>class
|attribute
|pseudo-class
>element
.
Note: pesudo-element
selector will not work in both (ie: ::before
).
span:where([cust-attr=""], :not([cust-attr])) {
text-decoration: underline;
}
span:is([cust-attr=""], :not([cust-attr])) {
color: red;
}
<div>
<span id='1' cust-attr="">Text 1</span>
<span id='2'>Text 2</span>
<span id='3' cust-attr='Foo'>Text 3</span>
</div>
Upvotes: 0
Reputation: 25587
Late to the party...
... or you could use CSS Selectors and be 10x as fast as both jQuery answers... :)
document.querySelectorAll("input:not([id]), input[id='']");
Upvotes: 15
Reputation: 237845
Basically, don't.
It's not good practice to put all your logic into the selector. It will end up being computationally highly expensive (because the parts need to be parsed out of a string before they are interpreted) and messy. Use the beauty of the filter
method instead:
$('span')
.filter(function(){
return !$(this).attr('cust-attr');
});
This removes all elements where cust-attr
is a non-empty string from the selection.
Upvotes: 6
Reputation: 111900
Why not just select all the SPANs first and then filter the selection down? E.g.
$('span').filter('[cust-attr=""],:not([cust-attr])')
Upvotes: 4