Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

jQuery $(this).data() is returning old values

I have the following code:

updateColors = function() {
  $(".color-preview").each(function() {
    return $(this).css('background-color', $(this).data('color'));
  });
  return null;
};

I put a breakpoint on the 3rd line, and type the following into the console:

> this
<div class=​"color-preview" data-observer=​"{"attr":​"data-color", "observe":​"btn_col"}​" data-color=​"#ffff00" style=​"background-color:​ rgb(153, 0, 255)​;​">​</div>​

> $(this).data('color')
"#9900ff"

As you can see, the actual element's data-color is #ffff00. However, jQuery's .data() method is returning #9900ff, which was the value of the element's data-color, but has been changed (and using the breakpoint, I can see that yes it has already changed).

like image 778
Mirror318 Avatar asked Aug 03 '16 03:08

Mirror318


2 Answers

jQuery only reads-through to data attributes with .data - that is, the data attribute will only be inspected the first time it is accessed (and never if the first access is an assignment).

Internally, jQuery it maintains it's own 'data cache' which otherwise has no relation to data attributes. This internal cache is primed through from the DOM data attributes on the first access of a given key.

If the goal is to always read and/or mutate the DOM attributes, use the .attr method instead.


The relevant parts from https://github.com/jquery/jquery/blob/master/src/data.js are shown below.

// Attempt read from the cache - if found, there is NO reading from DOM/data-*
// The key will always be camelCased in Data
data = dataUser.get( elem, key );
if ( data !== undefined ) {
   return data;
}

// Attempt to "discover" the data in
// HTML5 custom data-* attrs
data = dataAttr( elem, key );

// ..

function dataAttr( elem, key, data ) {
    var name;

    // If nothing was found internally, try to fetch any
    // data from the HTML5 data-* attribute
    if ( data === undefined && elem.nodeType === 1 ) {
        // ..

        // Make sure we set the data so it isn't changed later
        // (NOTE: This operation adds the data to the cache
        //  and prevents reading any updated data-* attribute values.)
        dataUser.set( elem, key, data );

See also:

  • jQuery Data vs Attr?
  • Difference between jQuery .data() and setAttribute
like image 99
user2864740 Avatar answered Nov 05 '22 01:11

user2864740


you have to remove the previous data like this before accessing it again if it is changed

$(this).removeData('color')
like image 5
Aditya Tomar Avatar answered Nov 05 '22 01:11

Aditya Tomar