This post introduces best jQuery practices you should follow:
Loading from CDN
Instead of storing jQuery on your server, choose to load it from popular CDNs. It will decrease the page loading time.
<!-- Don't -->
<script src="/vendor/jquery/jquery.min.js"></script>
<!-- Do -->
<script src="//ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
Below is the list of popular CDNs which you can find jQuery on:
There are some good practices, not only for jQuery, but also for other CSS, JS libraries when loading them from CDN:
Provide a fallback version in your server if loading from CDN fails
<script src="//ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script>window.jQuery || document.write("<script src='/vendor/jquery/jquery.min.js'>\x3C/script>");</script>
Choosing the compressed version
<!-- Don't -->
<script src="//ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.js"></script>
<!-- Do -->
<script src="//ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
Placing the script at the bottom of page
<!doctype html>
<head>
...
<!-- Don't -->
<script src="//ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
</head>
<body>
...
<!-- Do -->
<script src="//ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
</body>
Using protocol-relative URL
Leaving http: or https: out of the URL. By doing this, the browser will choose to load the https URL of script if your page is severed under https.
<!-- Don't -->
<script src="http://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<!-- Do -->
<script src="//ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
Shorthand for the ready event
// Usual way
$(document).ready(function() {
...
});
// The shorthand
$(function() {
});
Naming jQuery object starting with $
With this naming convention, we can know whether or not a variable is a jQuery object.
// Don't
var form = $('#contactForm');
// Do
var $form = $('#contactForm');
Using $this
Use $this variable at the beginning anonymous functions, for example, inside an each loop:
// Don't
$('li').each(function() {
$(this).on('click', function() {
$(this).addClass('active');
});
});
// Do
$('li').each(function() {
var $this = $(this);
$this.on('click', function() {
$this.addClass('active');
});
});
Someone prefer to use that or self. Don't forget to prefix with $ if it's jQuery object.
Caching jQuery objects
If a jQuery object is used multiple times, caching it will save the performance of script.
// Don't
$('.menu li').each(function() { ... });
$('.menu li').each(function() { ... });
// Do
var $items = $('.menu li');
$items.each(function() { ... });
// Reuse it
$items.each(function() { ... });
Chaining method
Chaining method is one of most powerful features of jQuery. It allows us to call multiple methods at the same time.
// Don't
var $a = $('#about');
$a.hide();
$a.addClass();
$a.fadeIn();
$a.hide();
// Do
$('#about').hide().addClass().fadeIn().hide();
// Better
// Add line-break and indent for readability
$('#about')
.hide()
.addClass()
.fadeIn()
.hide();
Creating new element
When creating new element, try to use jQuery methods to manipulate the element instead of giving full HTML code.
// Don't
var $hidden = $('<input class="form-control" type="hidden" name="foo" value="bar" />').appendTo('#form');
// Do
var $hidden = $('<input/>')
.addClass('form-control')
.attr('type', 'hidden')
.attr('name', 'foo')
.val('bar')
.appendTo('#form');
// Or
var $hidden = $('<input/>', {
class: 'form-control',
type: 'hidden',
name: 'foo',
value: 'bar'
})
.appendTo('#form');
Don't mix CSS with jQuery
Don't set the CSS styles for element directly. Using CSS class instead.
// Don't
$('#button').css({
'background-color': '#5cb85c',
'border-color': '#4cae4c'
});
// Do
.success {
background-color: #5cb85c;
border-color: #4cae4c;
}
$('#button').addClass('success');
Optimizing selectors
Using ID selector
To retrieve the element by given ID, jQuery uses native document.getElementById() method which is faster than using Sizzle.
// Don't
$('#wrapper #inner');
$('div#inner');
$('.wrapper #inner');
// Do
$('#inner');
Using ID-based selector
// Don't
$('#container .row');
// Faster
$('#container').find('.row');
Specificity
Be specific on the right-hand side of your selector, and less specific on the left.
// Unoptimized
$('div.data .gonzalez');
// Optimized
$('.data td.gonzalez');
Avoid the universal selectors
// Slow
$('div.container > *');
// Faster
$('.container').children();
Avoid implied universal selectors
It's recommended to prefix a pseudo-class selectors (beginning with :) with a tag name or other selector. Otherwise, the universal selector (*) is still implied.
// Don't
$('.category :radio');
// Do
$('.category input:radio');
Using filtering methods instead of pseudo selectors
When possible, use jQuery filter method instead of pseudo selectors. jQuery then uses querySelectorAll method which is faster than using Sizzle methods.
// Don't
$('.item:first')
// Do
$('.item').eq(0)
Don't use JS inline to bind events
Always using jQuery to bind events:
<!-- Don't -->
<button id="saveButton" onclick="javascript: save();">Save</button>
// Do
$('#saveButton').on('click', function() {
...
});
Using custom namespace for events
By using custom namespace, you can easily unbind the exact event without affecting to other event handlers which are bound to the element.
$('#saveButton').on('click.bv', function() {
...
});
// Later, it's possible to unbind the event handler
$('#saveButton').off('click.bv');
Don't put all parameters in Ajax URL
When sending data to remote URL using an Ajax request, use data option to send them instead of putting in the URL.
// Don't
$.ajax({
url: '/remote/url?param1=value1&param2=value2...'
}});
// Do
$.ajax({
url: '/remote/url',
data: {
param1: 'value1',
param2: 'value2'
...
}
});
In the case the parameter might be too long (the article's content, for example), consider to use the POST method for both Ajax requests and the back-end.