views:

1124

answers:

2

I'm developing code using jQuery and need to store data associated with certain DOM elements. There are a bunch of other questions about how to store arbitrary data with an html element, but I'm more interested in why I would pick one option over the other.

Say, for the sake of extremely simplified argument, that I want to store a "lineNumber" property with each row in a table that is "interesting".

Option 1 would be to just set an expando property on each DOM element (I hope I'm using the term 'expando' correctly):

$('.interesting-line').each(function(i) { this.lineNumber = i; });

Option 2 would be to use jQuery's data() function to associate a property with the element:

$('.interesting-line').each(function(i) { $(this).data('lineNumber', i); });

Ignoring any other shortcomings of my sample code, are there strong reasons why you would choose one means of storing properties over the other?

+1  A: 

Using $.data doesn't modify the DOM. You should use $.data. If you're creating a plugin then you should store one object in $.data with properties on that object as opposed to storing each of those properties as different key/value pairs in the $.data structure.

Ken Browning
note that that's how the $.data repositories work, so you're just adding one extra indirection level. if you advice on this because of namespace isolation, it can just as effectively done with a plugin-specific prefix. granted, this would only be significant if storing lots of data and/or accessing it on a tight loop. anywhere else, it's a matter of style preference
Javier
Yeah, I'd avoid modifying the DOM. IIRC, it can cause some pretty bad memory leaks on some browsers.
seth
@Javier: I was relaying what the documentation for $.data advises. I agree that the extra layer of indirection doesn't seem all that valuable but docs state its best practice.
Ken Browning
+4  A: 

If you are authoring a plugin you should use $.data. If you need to store the attribute often and rarely need to query the DOM for it then use $.data.

Having said that for all my client applications I tend towards storing custom DOM attributes on the DOM element themselves so that I can query them later using the attribute [] selector:

var domElement = $('.interesting-line[lineNumber=' + lineNumber + ']').get(0);

This is much more readable than iterating the wrapped set calling .data() on each item. Often I am inter-oping with another 3rd party library that operates on a DOM element so having quick and easy access to the DOM element via this mechanism keeps the code readable.

It's as easy as storing a lookup table mapping lineNumbers to elements, however the expando attribute technique is less at-risk of leaking memory in comparison, since you are not storing references to DOM elements that you need to cleanup later.

Crescent Fresh