Reputation: 1992
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
Reputation: 206008
"*"
selector or rather "body *"
(as suggested by @cars10m) to skip the head
children..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
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