Terry
Terry

Reputation: 1992

jQuery Find Elements if any of the attributes contains a value

What's the best way to select elements where any attribute contains a specific string?

I know the following works if I know the attribute name:

// Select any element where data-test attribute contains rbl-value
var items = $("*[data-test*='rbl-value']");

But I could have rbl-value inside any attribute and I want to be able to process those elements/attributes.

<div class="rbl-value:itemClass">
   <p>Don't process me...</p>
   <p data-inputname="rbl-value:inputName">data-inputname should be processed.</p>
</div>

Assuming there is clever solution, how performant is it?

Upvotes: 1

Views: 317

Answers (2)

Roko C. Buljan
Roko C. Buljan

Reputation: 206008

  • Loop (expensively) all your elements using the "*" selector or rather "body *" (as suggested by @cars10m) to skip the head children.
  • Use Element.attributes and its .name and .value properties:

const ELS_all = document.querySelectorAll("*");

ELS_all.forEach(EL => {
  [...EL.attributes].forEach((a) => {
    if (/rbl-value:/.test(a.value)) {
      console.log(a.name, a.value);
    }
  })
});
<div class="rbl-value:itemClass">
   <p>Don't process me...</p>
   <p data-inputname="rbl-value:inputName">data-inputname should be processed.</p>
</div>

Then to extract the specific rbl-value:<THIS STUFF HERE> you could use this small Regular Expression:

/(?<=rbl-value:)\w+\b/g

const a = { // Just to imitate the returned El.attributes entry object 
  value: "asd123 ghjkasd rbl-value:inputName hjlqwezuo rbl-value:something asd"
};

const rblValues = a.value.match(/(?<=rbl-value:)\w+\b/g);
console.log(rblValues)

Upvotes: 1

Carsten Massmann
Carsten Massmann

Reputation: 28196

OK, since "all attributes" includes not only all attributes starting with "data-" but all other "possible" attributes a DOM-element might have, the solution is not that simple.

What about concentrating on "the usual suspects"? I. e. what about looking at a certain list of attributes for each element?

Maybe the following could be a starting point?

$("body *").not("script").each(function(){
  console.log(JSON.stringify(Object.entries({tag:this.tagName,dataset:this.dataset,id:this.id,name:this.name,href:this.href,class:this.className})));
});
<script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>
<div class="rbl-value:itemClass">
   <p>Don't process me...</p>
   <p data-inputname="rbl-value:inputName">data-inputname should be processed.</p>
</div>

Obviously, this needs further work and is not a "complete answer". But maybe this is a step in the right direction?

Upvotes: 0

Related Questions