DotNetCurry Logo

Important Tips Every jQuery Developer Should Know

Posted by: Suprotim Agarwal , on 1/17/2015, in Category jQuery and ASP.NET
Views: 51313
Abstract: Every jQuery developer must know these tips shared in this article while working on their projects and websites.

There are number of ways to achieve a task in jQuery but knowing what to use and when to use a particular, separates you from other developers. This article contains some basic guidance that every jQuery Developer must keep in mind while working on their projects and websites.

 

1. stopPropagation or preventDefault or return false?

Developers new to stopPropagation, preventDefault and return false are often confused with which technique to use and when. This section will clear that confusion.

stopPropagation()

To understand stopPropagation, we need to understand event bubbling first. Let’s take an example. Let us say you have a link <a> inside a <div> as shown here:

<div id="divone">
    <a href="#" id="aone">Click me</a>
</div>

The click event is hooked on both the link and the div:

$("#divone").click(function (e) {
    alert("div clicked");
});

$("a").click(function (e) {
    alert("link clicked");
});

When you click the link, the click() event fires and a function runs which displays "link clicked" in an alert box. The event however, doesn’t stop there. You will see another alert box which says "div clicked". In other words, even though you clicked the <a>, the <div> being its ancestor element, also receives the click event. This is called event bubbling or event propagation.

So in order to stop the event from bubbling, you use stopPropagation in the following manner:

$("a").click(function (e) {
    alert("link clicked");
    e.stopPropagation();
});

Now when you click the link, the click event will fire and a function will run that displays "link clicked" in an alert box. However due to e.stopPropagation, the event won’t bubble up. That’s why you won’t see the second alert box.

preventDefault()

If you want to prevent the web browser’s normal response to an event, use preventDefault(). By default, when you click on the hyperlink, the normal response of the event is to transfer you to the url represented in the hyperlinks href attribute. Let’s take the same example again. Define the hyperlink inside the div as follows:

<div id="divone">
    <a href="http://www.jquerycookbook.com" id="aone">Click me</a>
</div>

Here clicking on the hyperlink transfers you to my new book’s homepage www.jquerycookbook.com. If you want to prevent this default behavior, use preventDefault() as shown here:

$("#divone").click(function (e) {
    alert("div clicked");
});

$("a").click(function (e) {
    e.preventDefault();
});

When you run the code now, you will see that clicking the hyperlink does not transfer you to the website as we have prevented the browser’s default action of the event.

However the “div clicked” alert does fire, as we are preventing the default, but not stopping event bubbling/propogation from occurring. If you want event bubbling from occurring too, then use both as shown here:

$("a").click(function (e) {
    e.stopPropagation();
    e.preventDefault();
});

Now we are doing both, so the browser doesn't follow the link and the div doesn't fire the event, hence we see no alert() box.

return false

return false is effectively a shortcut for calling stopPropagation() and preventDefault(). It is a way of telling jQuery to prevent the default and stop bubbling. Most of the times, you wouldn’t want to call stopPropagation, so I strongly advise that instead of using return false, use preventDefault() in your code.

2 - Some Selector Tips

Here are some selector tips that you can use to improve selector performance:

a. When possible, use the ID selector to select elements in your code.

b. Do not prepend the tag name before the selector. So if you have the following:

<input type="text" id="code" value="54325454" />

..do not use $("input#code"), rather use $("#code").

c. Wherever possible, use the method over a filter for better performance. So instead of $( "div:has(p)") you can use $("div").has('p'). Here .has() uses the native DOM querySelectorAll() method and hence is theoretically faster than :has.

d. Instead of using :lt and :gt selectors, use slice() instead.

e. It is recommended to precede a pseudo selector like :text with a tag name or some other selector; otherwise, the universal selector ( "*" ) is implied. In other words, $(":text") is equivalent to $( "*:text"), so $("input:text") should be used instead.

f. Instead of the Attribute Not Equal Selector, use .not() wherever possible for a slight performance advantage.

g. Instead of filters, use their equivalent attribute selectors. Eg: use $('[type=image]' instead of $(':image')

Further Reading:

http://learn.jquery.com/performance/optimize-selectors/

http://api.jquery.com/?s=selectors

3 - Use attr() or prop()

attr() deals with attributes while prop() deals with properties. Consider this markup:

<input type="text" value="original" />

The input field has the attribute "value". This is the default value you entered and this attribute does not update itself when the user interacts with it. So if the user changes the value in the input field, it is the property "value" that changes in the DOM Tree and not the attribute "value".

I have set up a jsfiddle demo to understand the difference between the two: http://jsfiddle.net/jquerycookbook/s1gsLcLb/

Run the demo and once you change the values of the textbox from “original” to something else, hit tab. You will see that attr() will return the original value but prop() returns the changed value.

So attributes do not change, but properties can be changed in the background by a user action (checking/unchecking a checkbox) or programmatically.

So when to use what? If you want to setup the default value for an HTML’s tag attribute, use attr(). However when you are setting properties on the window or document objects, you should always use prop().

Although I used this textbox example for explanation purposes, in true sense, neither .attr() nor .prop() should be used for getting/setting value. You should use the .val() method instead.

Before jQuery 1.6, we just had attr().

Further Reading: http://blog.jquery.com/2011/05/12/jquery-1-6-1-released/

4 - <script> in head or body?

In an HTML file, you can refer to your JavaScript at two places - within the <head>, or just before the closing </body> tag. The web browser processes an HTML page from top to bottom, and executes any JavaScript that it finds between <script> tags, along the way. Due to this, the loading of the page is blocked if one of your scripts takes time to execute. Therefore, it's better to put the scripts just before the closing tag of body element, which ensures that your script is run, after the DOM is loaded.

In some of my articles and even my book, I often chose to put the script inside the <head> tag, but this is only for the sake of readability. But I also make sure to use $(document).ready() or the shortcut $(function(){ }) which ensures that the script will be executed only when the browser has loaded all of the content in the HTML document. Hence I am achieving the same effect as that of putting the script just before the closing </body> tag.

Having said that, keep in mind that by having your scripts at the bottom of the page, you can completely avoid the use of $(document).ready(). In fact, in all my production ready applications, I use my scripts at the bottom of the page.

5 - Difference between this, $this and $(this)

Let us understand the difference between this, $this and $(this) with an example. Consider the following code:

$('div').each(function () {
    var $this = $(this);
    $this.css("background-color", "blue");
    $this.slideUp('3000');
    $this.slideDown('3000');            
});

Here we are looping over a bunch of div’s using each(). Once you are inside the loop, this refers to the DOM element which is not a jQuery object. So to make it a jQuery object and to run jQuery methods on it, we do $(this).

Now look at this statement: var $this = $(this);

If you’re going to reference the DOM element multiple times in the code, which we are doing in our example; then for performance sake, you should get a jQuery reference to it and then save that to a variable. Here $this is that variable. This is also called as caching the selector as it is expensive to run the jQuery function $(this) each time. So storing the output in a variable allows you to re-use the selector over and over, without calling the jQuery function again.

Note: Don’t get confused with $this. You can call it anything you like. I usually refer to variables that contain jQuery objects as $variablename.

I hope these tips helped! You can also check out several other performance tips in my new book www.jquerycookbook.com

Was this article worth reading? Share it with fellow developers too. Thanks!
Share on LinkedIn
Share on Google+
Further Reading - Articles You May Like!
Author
Suprotim Agarwal, MCSD, MCAD, MCDBA, MCSE, is the founder of DotNetCurry, DNC Magazine for Developers, SQLServerCurry and DevCurry. He has also authored a couple of books 51 Recipes using jQuery with ASP.NET Controls and a new one recently at The Absolutely Awesome jQuery CookBook.

Suprotim has received the prestigious Microsoft MVP award for nine times in a row now. In a professional capacity, he is the CEO of A2Z Knowledge Visuals Pvt Ltd, a digital group that represents premium web sites and digital publications comprising of Professional web, windows, mobile and cloud developers, technical managers, and architects.

Get in touch with him on Twitter @suprotimagarwal, LinkedIn or befriend him on Facebook



Page copy protected against web site content infringement 	by Copyscape




Feedback - Leave us some adulation, criticism and everything in between!
Comment posted by bala on Sunday, January 18, 2015 9:06 PM
Nice article
Comment posted by Joe Conlin on Monday, January 19, 2015 9:29 AM
I'm confused in your first example of stopPropogation. Why in the world would you want to hook into the click (or whatever) event of both the link AND the div containing it? I always choose one or the other and as a result would never have an issue of bubbling.
Comment posted by Suprotim Agarwal on Monday, January 19, 2015 7:52 PM
@Joe: the div and anchor example was just for explanation purposes. Another example could be a ul that has a bunch of li's containing anchors. Typically you would have the click bound to both li's (say for toggling expand/collapse icons) and anchors. However your requirement could be that when you click on an anchor, you don't want the event to bubble up to the li. That's where stopPropogation comes in.

Selfplug: I have the following example in my book jquerycookbook.com about a nested treeview #decor.

$('#Decor li').on('click', function (e) {
    e.stopPropagation(); // prevent links from toggling the nodes
    $(this).children('ul').slideToggle();
});

Here we attach a click event on every li item of the list. Observe that I have used e.stopPropagation(). This is especially done to stop the event from propagating from the anchor element, within the li. So if the user clicks on a link inside the tree, the nodes won’t toggle and that’s what we want. To understand this better, try commenting out the e.stopPropagation() code, click the link and you will observe that the nodes collapse when the hyperlink is clicked. This is not the desired behavior and that’s why we have stopped the event from propagating.
Comment posted by Ramesh on Tuesday, January 20, 2015 3:07 AM
Very nice..............
Comment posted by vishal on Tuesday, January 20, 2015 3:35 AM
+1
Comment posted by Sumit on Tuesday, January 20, 2015 6:18 AM
+1
Comment posted by SHEKHAR GURAV on Monday, February 2, 2015 9:57 AM
Thanks for nice article. If possible please write more on grid CRUD functionality handling by j query do's and donts.
Comment posted by jamshad hashmi on Monday, February 23, 2015 3:30 AM
Greate pieces. Keep writing such kind of
information on your blog. Im really impressed
by your site.
Hey there, You’ve performed a great job. I will certainly digg it
and in my view recommend to my friends. I’m sure they will be benefited from this web site.


http://naveedsoft.com/