8

Is there a way to find all the elements with attributes that start with a particular string?

I am using Mootools framework and this is what I have tried:

$$('*[data-media-*]');

But it just outputs all the elements in the page.

So is there a way to get all the elements in the page that have attributes that start with, data-media-?

BoltClock
  • 700,868
  • 160
  • 1,392
  • 1,356
jnbdz
  • 4,863
  • 9
  • 51
  • 93

4 Answers4

2

You can approximate something like this by iterating through the attributes for each element in the container, and seeing whether the attribute name matches a regex for what you are looking for:

For example, in this jsFiddle, I am looking for li elements with the data-media-tv and data-media-dvd properties.

You can tailor the regex to return only what you want to see. Want to only see elements that have a data-media-* (like in your question)? Here you go.


Keep in mind that this isn't exactly scalable. Because we are iterating through every single element on the page, and checking every single attribute (but returning early if found), this can and will probably be slow for large pages.

Limit this to ONLY the container you want to search, or only the elements you want to iterate through! If you run this against document.body, it will iterate through every single element in the page, I will not be responsible if your house burns down as a result. :)


Here it is function-ized:

function attrMatch(elements, regexp) {
    // Iterate through all passed-in elements, return matches
    var matches = elements.filter(function(li) {
    var numAttr = li.attributes.length;
    for(x=0;x<numAttr;x++) {
        var attr = li.attributes[x];
        return attr['name'].test(regexp);
    }
    });

    return matches;
};

In elements, only pass in the elements you want to check, possibly selected via $$. If you want to check all elements in a container element, replace elements with container and container.getChildren() in each instance of element, above.

Julian H. Lam
  • 25,501
  • 13
  • 46
  • 73
2

try this jsfiddle just know the (common) index/position of the attribute data-media-* and use in the code accordingly.

Teena Thomas
  • 5,139
  • 1
  • 13
  • 17
1

you can filter elements that you already have to return ones with matching data-* attributes.

Elements.implement({
    filterData: function(substring){
        return this.filter(function(element){
            var attribs = element.attributes,
                len,
                ii = 0;

            for (len = attribs.length; ii < len; ++ii) {
                if (attribs[ii].name.indexOf('data-') === 0 && attribs[ii].name.indexOf(substring) !== -1) {
                    return true;
                }
            }
        });

    }
});

console.log($$("div").filterData('foo'));
console.log($$("div").filterData('bar'));
console.log($$("div").filterData('oba'));

in action: http://jsfiddle.net/dimitar/pgZDw/

downside: you already need to pass it on a collection of elements that make sense, eg. div.foo or #someid *

a more elegant solution would be to add a :data() pseudo to Slick:

(function(){
    // cache reusable string 
    var data = 'data',
        hyphen = '-',
        // set the fallback via XMLSerializer, if no outerHTML (eg. FF 2 - 10)
        XS = this.XMLSerializer && new XMLSerializer();

    Slick.definePseudo(data, function(value){
        return (this.outerHTML || XS.serializeToString(this)).test([data, value].join(hyphen));
    });
}());


console.log($$("div:data(foo)"));
console.log($$(":data(media-)"));

updated example: http://jsfiddle.net/dimitar/pgZDw/3/

Dimitar Christoff
  • 26,147
  • 8
  • 50
  • 69
  • I think I could add it to Slick. Anyways it wouldn't be a bad idea for me to look at Slick's code. – jnbdz Sep 18 '12 at 17:15
  • Also I could just do: $$('*')... But that is a bit of a overhead... One thing I am worried about is performance... – jnbdz Sep 18 '12 at 17:18
  • 1
    your problem is the need to wildcard. looking for a particular data attribute in an element is easy... when you wildcard you need to walk all attributes and that's expensive - like you say, what happens if you pass it * as selector? you could also scan the outerHTML for it, may be faster... – Dimitar Christoff Sep 18 '12 at 17:31
  • 1
    see updated response for an example via custom pseudo. crude and check reliability of outerHTML for cross-browser but this will be the fastest. downside: only looks for data-string* and not data-*string but you can tweak this. – Dimitar Christoff Sep 18 '12 at 17:40
-3
$$('div[attrName="attrnameValue"]').each(function() {
    // `this` is the div
});
BoltClock
  • 700,868
  • 160
  • 1,392
  • 1,356
Alvin Pradeep
  • 618
  • 4
  • 13