Bug Tracker

Opened 8 years ago

Closed 8 years ago

Last modified 8 years ago

#10027 closed bug (wontfix)

jQuery.hasData returns false for elements with HTML5 data- attributes in the markup

Reported by: ego@… Owned by: Rick Waldron
Priority: blocker Milestone:
Component: data Version: 1.6.1
Keywords: Cc:
Blocked by: Blocking:

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 (10)

comment:1 Changed 8 years ago by anonymous

As requested, here is a jsFiddle demonstrating above: http://jsfiddle.net/sNKrd/1/

(view with eg Firebug console enabled)

comment:2 Changed 8 years ago by Rick Waldron

Component: unfileddata
Owner: set to Rick Waldron
Priority: undecidedblocker
Status: newassigned

comment:3 Changed 8 years ago by Rick Waldron

Milestone: None1.6.3

comment:4 Changed 8 years ago by Rick Waldron

Further reduced test case: http://jsfiddle.net/rwaldron/96qVc/

comment:5 Changed 8 years 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:6 Changed 8 years ago by dmethvin

Blocking: 10026 added

(In #10026) See discussion in #10027 though.

comment:7 Changed 8 years ago by dmethvin

Resolution: wontfix
Status: assignedclosed

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 8 years ago by Rick Waldron

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:9 Changed 8 years ago by dmethvin

Milestone: 1.6.3

comment:10 Changed 8 years ago by Rick Waldron

Blocking: 10026 removed

(In #10026) We will not be directly writing to data-* attrs with the jQuery data api

Note: See TracTickets for help on using tickets.