2

Is there a way in jQuery to select all elements with "data-*" attribute name.

<div data-user="1">
    <span data-name="Richard"></span>
    <label></label>
</div>

Like on the sample HTML above I want to select data-user and data-name elements. The problem is "data-" attribute can be anything (like data-abc) that is why I want to select attributes with "data-*". I have looked at all jQuery attribute selector and cant find anything that does what I need. I cant use contains since text inside an element might have data- prefix.

Richard Heath
  • 349
  • 3
  • 12

5 Answers5

4

jQuery doesn't really have such a method, other than the attributes selectors you've ruled out.
You'd have to filter or just make your own method, like so :

jQuery.extend(jQuery.expr[':'], { 
    data: function(el) { 
        return !jQuery.isEmptyObject( $(el).data() );
    }    
});

that can be used like

$('*:data')
$('div:data')
$('.class:data')

etc. and returns only the elements that has data associated with it

FIDDLE

adeneo
  • 312,895
  • 29
  • 395
  • 388
1

Here is some vanilla HTML5:

Array.prototype.filter.call(
   document.querySelectorAll("body *"), 
   function(node) { 
      return Object.keys(node.dataset).length > 0;
   }
)

And some jQuery:

$("body *").filter(
   function() { 
      return !$.isEmptyObject(this.dataset) 
    }
)
Malk
  • 11,855
  • 4
  • 33
  • 32
0

See the JQuery API Documentation regarding the Attribute Contains Selector. Thias should get you started.

eyoung100
  • 168
  • 9
  • no. that's not helpful. the link is about attribute values and the OP is asking about attribute names I don't down vote answers but someone else might, so you might want to delete your answer – Stephen Thomas Apr 15 '14 at 23:14
0

I don't think there's an easy solution to this problem. What I will do is

//Get all the elements in the document and filter those that have data-* attribute

$('*').filter(function() {
   var attrs = this.attributes; //get the attributes array-like object for each DOM element

   for (var i=0, len=attrs.length; i<len; i++) {
     var attr = attrs[i];
     if (attr.name.match(/^data-/)) {
       return true;
     }
  }
});

I tested this and it worked.

Akinkunle Allen
  • 1,299
  • 12
  • 19
0

You could roll through all the DOM elements and find just the ones with data elements...

var i, max, all = document.getElementsByTagName("*");

for ( i=0, max=all.length; i < max; i++ ) {
    // Do something with the element here
    var data = $( all[i] ).data();
    if( !$.isEmptyObject( data ) ){
        //if you find a non-empty object, the element has a data-* attribute, do something with it.
        console.log( data );
    }
}
Robert Munn
  • 778
  • 7
  • 12