jQuery .data() does not work, but .attr() does
.attr("data-itemname", "someValue")
modifies the DOM.
.data("itemname", "someValue")
modifies the jQuery cache.
To get this working in following Javascript and in addition in CSS you have to set both.
theaterA.find(".someLink").attr("data-itemname", "someValue");
theaterA.find(".someLink").data("itemname", "someValue");
This is the result of a misunderstanding: data
is NOT an accessor for data-*
attributes. It's both more and less than that.
data
is an accessor for jQuery's data cache on the element. That cache is initialized from data-*
attributes if there are any present, but data
never writes to the attributes, nor does changing the attribute change the data cache after initialization:
const div = $("[data-example]");
console.log('div.data("example"):', div.data("example"));
console.log('div.attr("data-example"):', div.attr("data-example"));
console.log('Using div.data("example", "updated")');
div.data("example", "updated");
console.log('div.data("example"):', div.data("example"));
console.log('div.attr("data-example"):', div.attr("data-example"));
<div data-example="initial value"></div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
data
also massages what it finds in various ways, guessing at data types, making data("answer")
on an element with data-answer="42"
a number, not a string, or even parsing things as JSON if they look like JSON:
console.log(typeof $("[data-answer]").data("answer"));
console.log(typeof $("[data-json]").data("json"));
console.log(typeof $("[data-str]").data("str"));
<div data-answer="42"></div>
<div data-json='{"answer":42}'></div>
<div data-str="example"></div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
If you want to use the attributes (both reading and setting them), use attr
, not data
. attr
is an accessor for attributes.
I ran into a similar "bug" a few days ago when working with .data()
and .attr('data-name')
for HTML5 data attributes.
The behavior you're describing is not a bug, but is by design.
The .data()
call is special - not only does it retrieve HTML5 data attributes it also attempts to evaluate/parse the attributes. So with an attribute like data-myjson='{"hello":"world"}'
when retrieved via .data()
will return an Object
while retrieval via .attr()
will return a string. See jsfiddle example.
Since .data()
does extra processing jQuery stores the results of attribute evaluation in $.cache
- after all, once a data attribute has been evaluated it would be wasteful to re-evaluate on every .data()
call - especially since data variables can contain complex JSON strings.
I said all that to say the following: After retrieving an attribute via .data()
any changes made by .attr('data-myvar', '')
will not be seen by subsequent .data()
calls. Test this out on jsfiddle.
To avoid this problem don't intermix .data
and .attr()
calls. Use one or the other.