1

Assuming example elements:

<a href="..." rel="...">...
<a href="..." rel="..." target="...">...

How can I match only the first element? I would like to tell jQuery to match only the <a> element which has an href and a rel attribute, but no other attributes. :not() requires me to mention specific attributes to exclude, but what about unknown ones?

aalaap
  • 4,145
  • 5
  • 52
  • 59
  • https://stackoverflow.com/q/12340737/8252164 Multiple attribute selectors – samuellawrentz Jul 12 '18 at 12:07
  • @CBroe good point. It seems performing an exclusive selector with `:not()` is your only choice, other than applying specific classes (which would be better in the long run) – Rory McCrossan Jul 12 '18 at 12:08
  • 2
    This feels a bit [XY problem-y](https://meta.stackexchange.com/questions/66377/what-is-the-xy-problem) … can you explain _why_ you would need to select an element based specifically on those criteria? Maybe there’s other ways. Or maybe at least the amount of non-allowed attributes can be limited to a certain set? – CBroe Jul 12 '18 at 12:12
  • Agree with @CBroe . Seems like an unusual requirement – charlietfl Jul 12 '18 at 12:23
  • I agree, it is an unusual requirement and that's what brings me here! – aalaap Jul 13 '18 at 10:02

4 Answers4

4

Use filter() and check the attributes length. Note that adding anything like class or data attributes would mean you would need to modify this

$('a[href][rel]').filter(function(){
   return this.attributes.length === 2;  
}).css('color','red')
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<a href="#" rel="foo" target="_blank"> Has target</a>
<a href="#" rel="foo" > No target</a>
<a href="#"  > No rel </a>
charlietfl
  • 170,828
  • 13
  • 121
  • 150
  • I had frowned upon other `filter` uses, because it simply felt like a shortcut for a `forEach` loop, but this bit is brilliant! – aalaap Jul 13 '18 at 10:04
1

You can use the not() and first() function for this, to select the first element in a collection & filter out the unwanted elements.

Example:

$("a[href][rel]").not("[target]").first();

In order to exclude items that contain other unknown attributes, you should use filter as the other answers advise.

This wouldn't be a good solution however, it would be much better to add a class to the elements you need to select, or have them in another div.

totallyNotLizards
  • 8,489
  • 9
  • 51
  • 85
0

Use .filter() with test condition to check element has only attributes length

$('a[href][rel]').filter(function() {
  return this.attributes.length == 2
}).addClass('a');
.a {
  background-color: red;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<a href="..." rel="...">...</a>
<a href="..." rel="..." target="...">...</a>
Satpal
  • 132,252
  • 13
  • 159
  • 168
0

You can use this.hasAttribute and further check this.attributes.length === 2 to confirm that <a> element has only two attributes:

$('a').each(function(){
   if(this.attributes.length == 2 && this.hasAttribute("href") && this.hasAttribute("rel")){
     $(this).addClass('selected');
   }
});
.selected{
  color: green;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<a href="..." rel="...">1111</a>
<a href="..." rel="..." target="...">222</a>
<a href="..." rel="...">333</a>
<a href="..." rel="..." target="...">444</a>
Ankit Agarwal
  • 30,378
  • 5
  • 37
  • 62