ggdx
ggdx

Reputation: 3064

jQuery data attr not setting

This appears very simple but I cannot see why it's not working. The selector is correct however the div .faqContent is simply not being updated with the data-height attribute.

$('.faqItem .faqContent').each(function(){
    var h = $(this).height();
    $(this).data('height',h);
});

I have checked that var h is correct, it is in colsole.log as correctly holding the height.

EDIT It's absolutely not conflict, and console shows no errors.

Upvotes: 32

Views: 25289

Answers (4)

T.J. Crowder
T.J. Crowder

Reputation: 1074238

The data function confuses a lot of people, it's not just you. :-)

data manages jQuery's internal data object for the element, not data-* attributes. data only uses data-* attributes to set initial values, and more, it guesses at what type you want those to be based on what they look like (so something that looks like a number is converted to a number; something that looks like JSON gets converted to an object). The data method never sets data-* attributes on elements, it only sets the data on its internal data object. That means the two (the internal data object and the attribute) get out of sync:

const t = $("#target");
let value;

// Getting the attribute always gets a string
value = t.attr("data-height");
console.log(`${value} (${typeof value})`);  // 1 (string)

// Using `.data`, jQuery will guess that because the attribute looks like a number,
// you want it converted to a number
value = t.data("height");
console.log(`${value} (${typeof value})`);  // 1 (number)

// `data` only sets the internal data object properties, not the attribute...
t.data("height", 2);

// ...so the attribute still has `"1"`
value = t.attr("data-height");
console.log(`${value} (${typeof value})`);  // 1 (string)

// ...even though the data object has 2
value = t.data("height");
console.log(`${value} (${typeof value})`);  // 2 (number)
<div id="target" data-height="1"></div>

<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>

If you want to actually set a data-* attribute, use attr:

$(this).attr("data-height", h);

const t = $("#target");
let value;

value = t.attr("data-height");
console.log(`${value} (${typeof value})`);  // 1 (string)

// `attr` converts whatever you give it to string
t.attr("data-height", 2);

value = t.attr("data-height");
console.log(`${value} (${typeof value})`);  // 2 (string)
<div id="target" data-height="1"></div>

<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>

But if you only want this information for future use, data is fine (assuming you're okay with its automatic type conversion), just don't expect to see it in the DOM inspector, because jQuery doesn't write this information to the DOM.

Upvotes: 110

Stephan Wagner
Stephan Wagner

Reputation: 990

JQuery .data() stores the value on the element itself, it won't add an attribute.

http://api.jquery.com/data/

If you want to add an attribute, use attr:

$('.faqItem .faqContent').each(function(){
    var h = $(this).height();
    $(this).attr('data-height', h);
});

http://api.jquery.com/attr/

Upvotes: 0

Felix
Felix

Reputation: 38102

.data() is only stores the associated new value in memory(or internally). It'll not change the attribute in the DOM hence you cannot see it updated using inspector tools.

To change the attribute, you can use .attr():

$('.faqItem .faqContent').each(function(){
    var h = $(this).height();
    $(this).attr('data-height',h);
});

Upvotes: 3

Adil Shaikh
Adil Shaikh

Reputation: 44740

You will not be able to see it in the element inspector but it is there as jquery set the data attribute internally.

try console.log($(this).data('height'));

Upvotes: 40

Related Questions