66

Recently I was coding away, and I ran into a weird issue. I was attempting to assign a data attribute to a new element I had created (via jQuery), only to discover it wouldn't actually assign the attribute. See the link below for an example, the code is listed below:

http://jsfiddle.net/y95p100c/1/

Any idea why this is happening? I've never stumbled into this...

var div = $("<div />")
$(div).data("foo", "bar")
console.log($(div)[0].outerHTML) // prints <div></div>
user1143682
  • 805
  • 1
  • 6
  • 8

2 Answers2

156

data doesn't set data-* attributes. It manages a data cache unrelated to data-* attributes. It initializes from data-* attributes if there are any present, but never writes to them. To write to an attribute, use attr.

Example: Updated Fiddle

var div = $("<div />")
$(div).attr("data-foo", "bar")
console.log($(div)[0].outerHTML)

What you're seeing is just one of the many ways this can be surprising. Another is that if your markup is <div id="elm" data-foo="bar"></div> and at some point you use $("#elm").data("foo") to get the value (and it will indeed be "bar"), then you do $("#elm").data("foo", "update"), the attribute remains data-foo="bar" but the data managed by data now has foo equal to "update". But the rule above explains it: data never writes to data-* attrs.

T.J. Crowder
  • 1,031,962
  • 187
  • 1,923
  • 1,875
  • 2
    interesting, I had also tried .prop() and it failed as well. Thanks! – user1143682 Sep 16 '14 at 18:55
  • 3
    @user1143682: That's because attributes aren't properties. :-) It's just that a lot of predefined attributes have reflected properties (`id`, `className`, `rel`, `src`, ...). (`prop` probably *did* create a property on the `div` element, but those aren't serialized when you look at `outerHTML`, because they're not HTML.) – T.J. Crowder Sep 16 '14 at 18:59
  • Ran into this exact same problem; good answer, helped clarify it for me. – Dan L Jun 18 '16 at 16:09
  • lol wow no wonder jQuery fell off the radar. Terribly confusing API. Doing a rewrite on this jQuery application is the pits. Thanks for the answer, was wondering wth is going on. – Spets Oct 31 '16 at 02:27
  • 1
    @Spets: While jQuery does absolutely have API issues (and this is one of them), I think a library used by [71.4% of **all** websites globally](https://w3techs.com/technologies/overview/javascript_library/all) can hardly be said to have "fallen off the radar." But if jQuery does start losing share, which I think is likely, I think it won't be down to its API, but rather to MVC/MVVM/choose-your-favorite-acronym-here in the form of React, Angular, Vue, Ember, ... – T.J. Crowder Oct 31 '16 at 07:22
  • 1
    wonder how many times I'm going to forget this, and keep coming back and see that I've already up-voted this question\answer. – dangel Jun 08 '19 at 02:14
  • @dangel - **LOL** I do that too! There's a particular SQL question... :-) – T.J. Crowder Jun 08 '19 at 07:19
24

jQuery imports the data- attributes when the element is loaded, but does not access it afterwards. The elements are stored in a jQuery internal structure. From the API:

The data- attributes are pulled in the first time the data property is accessed and then are no longer accessed or mutated (all data values are then stored internally in jQuery).

lonesomeday
  • 233,373
  • 50
  • 316
  • 318