9

How can I use JQuery to search for elements, that have a specific attribute value, regardless of the attribute tag?

Like:

$("[*='myvalue']")

should find

<a href="target.html" target="myvalue">...
<tr change="myvalue">...

The first one, because of the "target" attribute, the second one for the "change" attribute.

Is there a better solution than just iterate over all attributes?

2

4 Answers 4

4

You can use a custom pseudo-selector to filter over the attributes.

Following is a jQuery way.

$.expr[":"].attrFilter = function(elem, index, val){
    var len = $(elem.attributes).filter(function () {
        return this.value === val[3];
    }).length;
    if (len > 0) {
        return elem;
    }
};
$('body *:attrFilter("value")').hide();

Fiddle Demo

The $.expr[":"].attrFilter, is an extension mechanism for custom selectors. You can also pass a parameter.


Syntax :

$.expr[':'].selector = function(elem, index, match) { 

}
  • elem is the current DOM element
  • index is the index of elem
  • match is an array that contains all information about the custom selector,where the parameter passed lies at 3rd index. (Reference 1,Reference 2)

    • match[0] – contains the full pseudo-class selector call. In this example :attrFilter("value")
    • match[1] – contains the selector name only. In this example attrFilter
    • match[2] – denotes which, if any, type of quotes are used in the parameter - expression. i.e. single (‘) or double (“). In this example it will be empty.
    • match[3] – gives us the parameters, i.e. what is contained in the brackets. In this example `value
Sign up to request clarification or add additional context in comments.

2 Comments

Why do you check against val[3] (the 3rd/4th element of the "val" array)?
The match attribute is passed as a array, where the parameter passed lies at 3rd index/4th element. Sorry, not able to find a perfect documentation of it. You can debug the match and check.
1

Yes the same approach will be followed here also.Reference

 var elements = document.getElementsByTagName("*");
 for (var i = 0; i < elements.length; i++) {
 var element = elements[i];
 var attr = element.attributes;
 for (var j = 0; j < attr.length; j++) {
    if (attr[j].nodeValue == 'myvalue') {
        element.style.backgroundColor = 'red';
    }
  }
}

Comments

0

Here's a function extension that you could use to find the elements you want.

jQuery(function($) {
  $.fn.filter_by_attr_value = function(value) {
    return this.filter(function() {
        // [].some() would be better here
        return $.grep(this.attributes, function(attr) {
            return attr.nodeValue == value;
        }).length;
    });
  };

  $('*').filter_by_attr_value('myvalue').css('background', 'lightgreen');
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<a href="target.html" target="myvalue">FOO</a>
<table>
<tr change="myvalue">
  <td>BAR</td>
</tr>
</table>
<div>not me</div>

Comments

0

This can be done without JQuery in plain JavaScript or VanillaJS as other moniker is called. I put include because most of the time we search substring:

var all  = document.getElementsByTagName("*");
for (el of all) for (attr of el.attributes) if (attr.nodeValue.includes("myvalue")) console.log(attr.ownerElement)

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.