19

If you put a "data-" attribute on an element:

<div id='x' data-key='value'>

then you can get the value via the jQuery ".data()" method:

alert($('#x').data('key')); // alerts "value"

The library uses a consistent camel-case converter for attribute names with embedded dashes:

<div id='x' data-hello-world="hi">

alert($('#x').data("helloWorld"));

The camel-case converter is a jQuery "global" function:

alert($.camelCase("hello-world")); // alerts "helloWorld"

However this all breaks down when the attribute name has a name with a single letter surrounded by dashes:

<div id='x' data-image-x-offset='50px'>

alert($('#x').data('imageXOffset')); // undefined

That's a little weird, because:

alert($.camelCase('image-x-offset')); // "imageXOffset"

So what's wrong? I think it has something to do with the mechanism used to go the other direction, converting an already camel-case name back into the dashed form. I can't pinpoint it in the code however.

Seems to be the same in 1.6.2 as in 1.6.3. (The form "image-x-offset" can be used to get the data, by the way.)

edit — if, for a given element, you access via the dashed form before attempting the camel-case form, then it works (and that tells me that this is definitely a bug :-)

Pointy
  • 405,095
  • 59
  • 585
  • 614
  • 1
    jQuery bug report here: http://bugs.jquery.com/ticket/10194 (submitted by @Pointy) – gen_Eric Sep 02 '11 at 17:07
  • jsFiddle for you: http://jsfiddle.net/hJDLY/1/ . Neat, it looks like the OP made that bug report! :-P – numbers1311407 Sep 02 '11 at 17:08
  • Thanks everybody! This ate my morning :/ – Pointy Sep 02 '11 at 17:09
  • Look on the bright side, you are contributing to jQuery! It's odd, looking at the source there's no immediately obvious reason why this occurs. It gets/sets the cached value with the same camelCase function. https://github.com/jquery/jquery/blob/1.6.2/src/data.js – numbers1311407 Sep 02 '11 at 17:13
  • 1
    You can also just go `$('#x').data('image-x-offset')` and it will get the data. It's not compulsory to use the camelCaps it seems. Looks like it's fixed in jQuery 1.7 so nice work anyway. – zuallauz Feb 26 '12 at 04:56

1 Answers1

14

You're right. The issue seems to be with the regex they use for conversion from camelCase to dashed.

rmultiDash = /([a-z])([A-Z])/g;

...as used here:

var name = "data-" + key.replace( rmultiDash, "$1-$2" ).toLowerCase();

...which results in:

data-image-xoffset

...instead of:

data-image-x-offset

Demo: http://jsfiddle.net/TLnaW/

So when you use the dashed version, when it looks for an attribute, it finds it with no need for a conversion, and then adds the camelCase version to the elements data in jQuery.cache.

Subsequent attempts will then work because the correct camelCase is now there, so it no longer attempts to get it as an attribute, and therefore no longer needs the faulty regex.

user113716
  • 318,772
  • 63
  • 451
  • 440
  • 1
    I stared at that when I saw it earlier, but I goofed up when trying to figure out exactly what it'd do durrr -- thanks!! – Pointy Sep 02 '11 at 17:41