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

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

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

$(this).removeData('color')