Ticket #10027 (closed bug: wontfix)
jQuery.hasData returns false for elements with HTML5 data- attributes in the markup
| Reported by: | ego@… | Owned by: | rwaldron |
|---|---|---|---|
| Priority: | blocker | Milestone: | |
| Component: | data | Version: | 1.6.1 |
| Keywords: | Cc: | ||
| Blocking: | Blocked by: |
Description
<table> <tr> <td id="test" data-priority="1">Description of status</td> </tr> </table>
$.hasData(document.getElementById('test')); // returns false
$('#test').data(); // returns Object { priority: 1 }
If HTML5 data attributes are recognised by the data() method then $.hasData() should also recognise them.
Change History
comment:2 Changed 22 months ago by rwaldron
- Owner set to rwaldron
- Priority changed from undecided to blocker
- Status changed from new to assigned
- Component changed from unfiled to data
comment:4 Changed 22 months ago by rwaldron
Further reduced test case: http://jsfiddle.net/rwaldron/96qVc/
comment:5 Changed 22 months ago by dmethvin
We are unfortunately overloading a lot of meanings onto the word "data" here based on different standards and conventions. Originally it was just the "data" representing jQuery's data-binding feature but we have asymmetrically extended it to include the "data" representing the data- attributes on an element.
The reason .hasData() exists is to provide a way for jQuery internals to determine if a jQuery data object (i.e., an entry in jQuery.cache) exists for a DOM element *without actually creating one*. That cannot be done with jQuery.data() because that method is documented to return a newly created and attached data object if none previously existed.
For performance reasons, we only grab the data- attributes once, the first time that jQuery.fn.data is called to read an attribute that is not defined, or when it is first called to read the entire data object (see #8909). (Note that jQuery.data doesn't pull in data- attributes, but *will* read the cached values once they are cached.) If you ask for data- attributes after that, you're using cached values and not the actual attribute values off the markup.
If you need to answer the question "Tell me if any data- attributes are on this element at all -- I haven't got any idea of their possible names", and you want to know the *current* state as opposed to the jQuery-cached-data state of those values, you'll need to do what jQuery.fn.data does -- enumerate *all* attributes, looking for ones starting data-. That could be expensive.
Can anyone come up with a common need for something like this? Since the internal jQuery.cache entry that jQuery.data() reads won't necessarily match up with the real-time data- attributes I think it might do more harm than good to provide it.
And yes, I think we've made a mess of this.
comment:7 Changed 21 months ago by dmethvin
- Status changed from assigned to closed
- Resolution set to wontfix
If you need to find out whether there are any data- attributes, use $().data() and a for/in loop to examine the result. The required semantics of .hasData() do not allow it to go looking for data- attributes.
comment:8 Changed 21 months ago by rwaldron
If you need a "hasData" solution, the following will sufficiently meet that need:
http://jsfiddle.net/rwaldron/Um8MF/
(function( $ ) {
$.fn.hasData = function() {
var data = jQuery(this).data();
for ( var prop in data ) {
return true;
}
return false;
};
})( jQuery );
console.log(
$("#a").hasData(),
$("#b").hasData()
);
comment:10 Changed 20 months ago by rwaldron
- Blocking 10026 removed
(In #10026) We will not be directly writing to data-* attrs with the jQuery data api
Please follow the bug reporting guidlines and use jsFiddle when providing test cases and demonstrations instead of pasting the code in the ticket.

As requested, here is a jsFiddle demonstrating above: http://jsfiddle.net/sNKrd/1/
(view with eg Firebug console enabled)