Check out my NEW training website for front-end web developers, FrontendMasters.com

5 Tips for Better jQuery Code

November 14, 2008


I’ve been coding using jQuery since shortly after it came out, and well — I’ve been using it almost every work day. Here is a few tips that have saved me time.


#1: Use data method instead of storing data inside the DOM.


The mistake I see people making all the time is this:



$(selector).attr(alt, this is the data that I am storing); 
// then later getting that data with
$(selector).attr(alt);

Why is this a bad thing? Because “alt” has absolutely no meaning whatsoever, as well as HTML is not meant to store data.

Instead use the data method in jQuery. It allows you to associated data with an element on the page.

$(selector).data(meaningfullname, this is the data I am storing);
// then later getting the data with
$(selector).data(meaningfullname);

This allows you to store data with meaningful names and as much data as you want on any element on the page. It is a really amazing utility and something I’ve come to rely on.

#2: Take advantage of jQuery’s built-in custom selectors.

jQuery has a plentiful amount of selectors that are beyond basic CSS selectors, so use them. Some that I use are:

#3: If you are Manipulating the DOM a lot, use livequery.

Note on March 21st, 2009: New in jQuery 1.3, the live method has adopted many of the same events of livequery into the core of jQuery.

Note on November 16th, 2008: If you understand event delegation, use it as an alternative to using livequery for attaching events.

When you add elements to the page a lot, attaching events to them and running functions on them then use Brandon Aaron’s livequery plugin. This way you can do things like:

$(div.edit).live(click, function(){ … });

Then whenever you add a div to the page with class “edit” it will attach that click event. This works for all other events, as well as if you want to run a function on an element right when it is added you can do this:

$(span.flag).live(function(){
// run this function when a span with class "flag" is added to the page
});

#4: Use jQuery form plugin to submit files via Ajax.

If you use Mike Alsup’s jQuery form plugin you can use it to submit files via Ajax. It uses a trick with an iframe to submit the data. Just put in an input type file, then use $(form).ajaxSubmit(); and you are good to go.

#5: Use classes as flags.

If you aren’t storing data, but need to set a flag on an element use a class. What do I mean by a flag? Well, for instance if you are in"edit mode"of a form you might use the class,“editing”.With jQuery you can add a class with the addClass method and then check later if an element has the class with the hasClass method.

Like this article? You'll like my NEW training website for front-end web developers!

Video workshops on jQuery, JavaScript, HTML5, web performance and more.
Upgrade your front-end developer skills!

73 comments

#1. Mike Branski on November 14, 2008

I’ve been using jQuery for a year and a half, and I have to admit I’ve never heard of the data() method; I wish I had. This is going to change things for me.

:eq(index) has definitely come in handy many times, but I remember it took a little while for me to find it.

I can’t even begin to count the number of times I’ve been asked, “Why don’t my event bindings work on newly added DOM elements?” I usually point people to the jQuery FAQ entry explaining it (which also suggests livequery()).

#2. Marc Grabanski on November 14, 2008

Mike: Everyone I’ve worked with doesn’t use the data method, so you are definitely not alone on that one. That was why I wrote these tips – I understand people know what they are doing, but some parts of the jQuery API are undiscovered by most.

#3. Matt Curry on November 14, 2008

I agree w/ Mike about #1. I’m a serial offender of sticking random data in various attributes. I had no idea data() existed.

#4. Matt Wood on November 14, 2008

Do you think you get get better performance by flagging with classes rather than flagging with .data()?

#5. Tom Sieron on November 15, 2008

I’ve been using jQuery for a few years now, but always viewed storing data in DOM as a bad thing, or rather some sort of a hack. I don’t see the benefits of this over storing data as plain javascript variables and in objects. Why would it be better or useful?

The tip with using classes as flags is something I need to reconsider, thanks! Keeping flags as javascript variables is easier on the eye for me as you don’t need to refer to DOM to do anything, but perhaps the added benefit of trying do bigger things with “conditional” CSS might be worth giving it a shot.

#6. Sean O on November 15, 2008

Marc, good tips. I tend to rely on rel attributes for data markers.
Did you use $.data() in the Google Maps mashup you demoed at jQuery Camp?

#7. Marc Grabanski on November 15, 2008

Matt Wood: I think performance is a non-issue. The real reason behind using CSS flags is that you can grab all the elements on the page that are flagged easily with a normal CSS query. Or you can also use the built-in hasClass method in jQuery to check for the flag.

Tom Sieron: Normal JavaScript objects and variables are great for storing things! The only reason you would ever want to use the data method is if you want to associate a piece of data with a specific element on the page.

Sean O: no I didn’t use data the method. That was just a simple demo, but you reminded me I really need to finish that tutorial!

#8. Michal Wojciechowski on November 16, 2008

Good tips. Just a little correction — the post suggests that [attribute=value] is a custom jQuery selector, while it’s actually defined in the CSS2 specification (http://www.w3.org/TR/CSS2/selector.html#attribute-selectors).

#9. Leandro on November 17, 2008

Thanks for the tip, didn’t knew about data method. It’s great, but sometimes you need to pass a value from the backend to that element, so a class or rel attribute is needed as data storage. Let’s say the item ID. What do you think is the best solution for that?
Imagine you need to pass many divs per records in a DB, and do operations with each div. How you say from backend to jQuery/javascript which ID is related to current div?

I’ll give livequery a try, looks very useful.
Thanks

#10. Marc Grabanski on November 17, 2008

Leandro: try using the metadata plugin.

#11. Tian on November 17, 2008

Hi Marc,
Many thanks for the .data() method – it looks very useful and, like the rest here, it has eluded my attention until now.
A question about its performance: where is the data actually stored? Are we bloating the DOM by adding large data elements to it, or is the data being stored in js variable space as say an associative array and cross-referenced by the element ID?

I have some reservations about using classes as flags. While I do use this technique a lot, it has always bothered me that my HTML markup will not pass a lint test what with all those missing classes. E.g. in Visual Studio the elements that are so adorned with these undefined classes don’t fall easy on the eye, yet I’ve never bothered to define dummy CSS classes to get rid of the warnings. I’ve always assumed that there would be a more standards-compliant way of achieving this … but I’m not so sure anymore now that one of my jQuery heroes is advocating this technique!

#12. gregf on November 17, 2008

Like everyone else thanks for letting us know about the data method. Something else I had no idea about is that jquery.form had a built in way of dealing with file uploads. That’s a really neat trick.

#13. Marc Grabanski on November 17, 2008

Tian: the data is stored in the jQuery reference to the object. Performance is a not an issue, that is what jQuery uses internally in the core.

Visual Studio barks if you don’t have any styles associated with the flag class. Just try adding a few flag classes to the style sheet and the errors will go away. As far as standards, if it helps you and makes sense to developers than who cares? To me classes are meant to be CSS flags, why not use them for JS flags as well – it makes perfect sense to me.

#14. Mike Rundle on November 17, 2008

Great tip on the .data() function, I haven’t seen that before. Going to be really useful.

One thing I’ve been doing that (to me) might be a good thing to tell people about is not to reference the same deep selector call multiple times. Calling $(this).parents(‘.parent’).find(‘span’) more than once in your function is probably not the best way of going about it as you’re relying on jQuery to query the DOM each time to find the handle to what you’re looking for. What I like to do is set a long selector query like that to a JS variable, and then work off that variable so it doesn’t have to be calculated all the time. Same thing as setting a counter variable before your for loop so you only have to do it once.

#15. Ozh on November 17, 2008

Damn. Didn’t know about data() neither. Thanks for this :)

#16. Joe McCann on November 17, 2008

Nice I have to agree with Mike Rundle and here’s an example:

var el = $(‘p.secondary’);

el.css(‘color’,‘#cecece’);
el.text(‘hello world!’);
el.append(‘

Another paragraph

’);


Instead of constantly referencing the element, $(‘p.secondary’), set it to a variable which “caches” it locally for quick reuse. Immensely efficient!

#17. Joe McCann on November 17, 2008

Just noticed that the append method up there actually used the paragraph tag that I inserted in there…just note that the text “Another Paragraph” is wrapped in a paragraph tag.

#18. Jahdur Rahman on November 17, 2008

I have opened the http://brandonaaron.net/docs/livequery/ livequery link. But I found an empty page. What’s wrong?

#19. Ben on November 18, 2008

Been using jQuery for a few months. data() is new to me also and is exactly what I need!!!!

#20. Jonas on November 18, 2008

Thank you for letting me know the existence of .data() Didn’t knew that eather.

@Jahdur Rahman: Try this link: http://docs.jquery.com/Plugins/livequery

#21. Marc Grabanski on November 18, 2008

@Jahdur Rahman: Either that or get livequery from Brandon Aaron’s github.

#22. olivvv on November 20, 2008

Most people do not understand what livequery implies, i.e, the dom to be periodically scanned.
They only understand it when they face performance problems on large dom operations.

I think it is much much more productive to teach people event delegation, rather than orientating them toward a pseudo-miraculous solution that will badly leak when thing get serious.

Event Delegation rules !

#23. Jeremy Martin on November 20, 2008

@olivvv

It is true that Event Delegation is a powerful technique, but it also needs to be approached with care. In most cases, it can be used for relatively infrequent events (such as clicks) with impunity, but more frequent events (such as mousemove, mouseover) can see very poor performance. Event Delegation requires inspecting the target of each and every event (of a particular type) that is fired. If that event is a mousemove, you can be performing a ridiculous amount of target inspections.

Bottom line is to understand the implications of all these techniques so that you can pick the best one for your current needs. Factors such as the frequency of DOM modification and the type of events you’re reacting to can make a world of a difference.

#24. Marc Grabanski on November 20, 2008

Jeremy Martin: Well said. It is not a simple answer to use one or the other. You have to understand them both to really get a grasp what to use in what situation. In general, livequery performs well enough until you get into intense DOM manipulation. That is why I suggested it, but still pointed people towards learning event delegation.

#25. Clinton Montague on November 21, 2008

Thanks for tip #1, very useful for those who don’t know. I used to use rels, alts, and anything else that I could think of until I found the data() function.

#26. JHollanti on December 19, 2008

Ding! You’ve got a fan :)

#27. Vik on December 20, 2008

I never heard of data() either until I found this page. :)

Can the 2nd parameter for data() be any type of variable, or does it have to be a string?

#28. Marc Grabanski on December 20, 2008

@Vik: You can store a function or an object as well, for instance.

set function in data with $(selector).data('foo', function(){ alert('bar'); });
$(selector).data('foo') ... returns function()
$(selector).data('foo')() ... alerts 'bar'

set object in data with $(selector).data('foo', { 'a':'b', 'c':function(){ alert('blah'); } });
$(selector).data('foo').a ... returns "b"
$(selector).data('foo').c() ... alerts "blah"

#29. David Clarke on January 08, 2009

Wow, data() seems to have struck a chord. Prior to discovering data() I was using the attr() function to add data to elements. As with data(), attr() can also be used to add arbitrary objects to elements. Obviously adding attr(“class”) to an element is going to have some potentially serious side affects whereas data(“class”) won’t but it is possible to add arbitrary attributes to HTML elements, i.e. you don’t have to repurpose valid HTML attributes such as “rel” or “alt”. I’m sure there are many opinions as to the efficacy of such an approach.

I guess my concern is more about whether either approach represents a good practice. Adding some data to an element in one module and accessing that data from another results in coupling so I would use it sparingly and only within a single module.

#30. Frank on January 16, 2009

Thanks for the tips! I’m still a bit of a newbie, but I love jQuery! I just found this awesome jQuery Cheat Sheet for the iPhone today. It’s really great. I’ve only had it for a day and it’s already making my life a lot easier.

http://itunes.apple.com/WebObjects/MZStore.woa/wa/viewSoftware?id=302090867&mt=8

Looks like there’s also a CSS Cheat Sheet from the same guys.

http://itunes.apple.com/WebObjects/MZStore.woa/wa/viewSoftware?id=301093674&mt=8

#31. Aamir Afridi on January 25, 2009

I wish i could have read about data() months ago. I, myself was not feeling good using html for storing data but never again. Thanks for this info

#32. Borellus on January 28, 2009

Cheers for that, very useful. :)

#33. earpick on February 06, 2009

Started using jQuery a few weeks ago and noticed the data method in the docs. Quite useful indeed. Wish I knew about it a few months ago when I was coding pure JS.

I suppose I built something rather similar to it though, as I have had .js classes representing the logic and data storage of the application, with an array of references to appropriate DOM elements for each of the objects. In essence, every DOM element would be represented by an object. Just had to ensure that when I stringify the objects into JSON for storage in a database that all the references to DOM are removed. Took a while to put together but worked well; I’m sure I could have slashed the development time by half had I used jQuery though.

#34. ege on February 13, 2009

Excellent post. Ditto with Mike Branski, I never heard of the .data() even though I have been using jQuery for some time. Very useful indeed.

#35. Bryan Kwon on February 22, 2009

What an great article on JQuery!!
Personally, I find this type of article a lot more useful than others that only touch surface of great effects.
I especially like the point on event delegation and livequery.

#36. Webdesign on February 24, 2009

Wonderful article about jQuery! Thx for the informations.

Greetings from DE

#37. Arun on March 06, 2009

I rarely comment on an article. But this one is too good. Wish I knew data 2 months back. Now I’ll have to rewrite my entire code. I hated doing it the attr way. Wish I had known all the best practices. I have already rewritten my code 3 times in 4 months!

Thanks Marc, you’re on my RSS reader now :)

#38. Richard on March 10, 2009

Tip 3 – jquery 1.3 has “live” method as standard, which is essentially the same as the livequery plugin.

Nice article! :)

#39. Marc Grabanski on March 10, 2009

Thanks Richard, this article was written before jQuery 1.3 came out.

#40. strony internetowe on May 02, 2009

interesting :)

#41. motoChristo on May 03, 2009

Marc,

I’ve been using jQuery at big commercial companies for a few years now and although everyone likes to use it not many project path decision makers ever seem to be all that concerned with really using it well as much as they just want the project out the door quick.

So I appreciate this tight concise list as it gives me a few more paths to get to the finish line that will undoubtedly help shed min/hours off future projects.

#42. Martin Leblanc on May 17, 2009

Wow! Great tips – especially the data one. I have a lot of jQuery code to optimize on my site: http://www.iconfinder.net

#43. Stanley @ SEOAdsenseThemes.com on May 26, 2009

I admit of being guilty to Tip #1. I did exactly that but having found out about data() function, I immediately modified my codes.

#44. Pokrate on June 01, 2009

Hi ,
I like your points.
Add this too :
// Checking the element type of the selected element, eg;
if($(this).is(‘form’)){
//welcome
}
else{
throw new Error(‘This block works only with a form’);
}

#45. Yunus on June 13, 2009

Thanks for it. its useful really..

#46. widi mawardi on June 23, 2009

hi.. good tips

#47. eric on August 05, 2009

does the PHP session can be used with this method?

#48. Scott Alex on August 21, 2009

Like everyone else here, I also didn’t know about the data function, and I have a sideproject that is going to need heavy modification now … =]

#49. James Collins on September 25, 2009

Hi Marc,

Thanks for intruducing me to the data() feature in jQuery. It looks like a great way to store and retrieve data once a page is loaded.

How would you recommend I store the data during page rendering?

For example, my PHP script retrieves product information from a MySQL database, and renders the page based on this data.

Obviously only the data() method can be used once the page loads, so how can I embed this product content in the HTML markup so it can be used once the page loads?

I’m currently using classes and the rel attribute, but it’s messy.

Thanks.

#50. KIZILSUNUR on October 16, 2009

Great article!

KIZILSUNGUR

#51. Skidoosh on November 19, 2009

For anyone who’s interested I’ve published V2 of a jQuery reference if you want to have a look at that it’s here: http://www.skidoosh.co.uk/jquery/jquery-selectors-and-attribute-selectors-reference-and-examples-v2/ I’ll be updating it for 1.3 in a few days.

#52. Arvii on November 23, 2009

Thanks for the light! Geez I didn’t know .data()…powerful indeed!

#53. jquereal on December 06, 2009

Hey Marc,
that’s the most useful few lines of code I’ve read on jQuery, inside 5 minutes, in many days :-)
THANKS A TON !!
I suggest you start a separate tips section with wise little snippets of code like the ones above. I’m sure you have more of those ;-D
(I also offer to help making a list of tips- if you want someone to share some of the grunt work. Serious.)

#54. Yorkshire Web Design on April 26, 2010

Great tips! Thanks for sharing. Ted

#55. Atul on July 30, 2010

Great Information, thanks for sharing this information.
Speciall .data() function is amazing, I never used that, this is going to change so many things for me.
Thanks again.
Atul K.

#56. JB on August 27, 2010

Curious for a better explanation on the use of .data. I would like to better understand your reasoning why it is better than using custom attributes on the dom element.
From my perspective one big advantage of using custom elements is you can use them in selectors too, like:

$(‘p [myAttr=myVal]’)

Which AFAIK, you can’t do with the data cache.

Thanks for the info though.

#57. Marc Grabanski on August 27, 2010

.data is much faster because you aren’t manipulating the DOM. What you are doing is just fine for smaller bits of strings, but you also can’t drop in a JavaScript objects or closures into DOM attributes.

#58. Reinder on October 05, 2010

Good shizzle. So, I’ve been wondering – what’s the best way to use .data()? Is it possible to add multiple data’s to one selector? And is it a good practice to add all your (relevant) data’s to one DOM Element? I can see myself forgetting to which element I attached something. All attachments have a name, which means they can be meaningful and do not have to rely on the ‘meaning’ of the element its attached to. Any thought on this?

#59. Marc Grabanski on October 06, 2010

If you want to select an element with data attached to it, then use a class as a flag in combination with data().

#60. P48l0 on October 12, 2010

cool, thanks man

#61. Nikhil on February 04, 2011

How to find whether the attribute ‘id’ is present in form tag or not

#62. porch on February 11, 2011

Nice tutorial, may thanks;)

#63. st.catharines web designer on March 05, 2011

Great tips. Thank you for sharing this!

#64. Alan Clarke on March 21, 2011

Top tips : >

btw re number 5, ‘“edit mode” of a form’ you might be interested in a plugin i wrote to make it easy to switch forms elements from edit mode to preview mode. Have a look, might come in handy! : >
http://plugins.jquery.com/project/toggleEdit
http://www.staticvoid.info/toggleEdit/

#65. binder dundat on June 19, 2011

awesome! many thanks

#66. kabin on July 06, 2011

i wrote to make it easy to switch forms elements from edit mode to preview mode

#67. mantolama on July 06, 2011

which means they can be meaningful and do not have to rely on the the element its attached to. Any thought on this?

#68. kontur on November 16, 2011

Wish I’d seen #2 earlier ,)

Number #3 probably needs updating with version 1.7, seeing as people are still refering to this information :)

#69. konteyner on November 19, 2011

to rely on the the element its attached to. Any thought on this?

#70. Konteyner on January 18, 2012

It’ very intersting.I like your sharing…

#71. theflea on March 06, 2012

interesting, but hope you had given the reasons to why and why not so we could judge for ourselves.

#72. web tasar?m on September 15, 2012

You people overreact the same way with every pre-sale. Just be patient, you’ll get tickets with everyone else when they go on general sale. It’s not like he’s Jeff Mangum or this is his last show ever or anything system

#73. web tasar?m on November 26, 2012

If you want to contact us if you need higher-level designs.

Leave a comment

Comment in textile images by gravatar