10 Best Practices with jQuery | Techbirds
10 Best Practices with jQuery
I’ll try to give an order to my tips, you will learn first the best practices to use with jQuery with its basic features then we’ll dig into more advanced features. Let’s start it, be focus!
1. Include and Load jQuery into your page
You could assume than loading jQuery is a simple task, and nothing could improve such a simple task. Well it’s wrong!
Let me show you some possible improvements:
Use this URL to include jQuery into your page :
This URL is used by the main websites out there. Using it will, luckily, load a cached version of your visitor saving him some precious milliseconds.
If the Jquery file is not cached, loading it through an external domain, will save you a request to load another file for your page (the browsers limit the client to execute two simultaneous requests per domain. Not more.)
Always used minified version for production. When you’re done developing your website, using the minified version is great to save some bytes to be transferred.
In case something goes wrong with your visitor, you should still include jQuery in your website directory and add this line at the bottom of your HTML page to load jQuery if Google failed:
window.jQuery || document.write(”);
2. jQuery Selector Optimization
One of the main things you do when you use jQuery is to select an element inside your DOM. But have you ever thought about performances while selecting an element? If the answer is no, then you should…especially when you are dealing with mobile development or heavy website using JavaScript and jQuery everywhere.
Build the right selector using jQuery is all about finding the right balance between giving enough information and giving too much. To be able to make the right choice, you need to be aware about the basics:
Your jQuery selector is read from right to left. A class can belong to ANY element of your HTML page.
An ID must be UNIQUE in your HTML page.
The fastest way to find an element with Jquery is by ID, then by Tag element, then by Class. So if you paid attention to the basics I just listed above, what should be definitely avoided? The following:
$(‘.myClass’).something();
If you still wonder why, then the answer is simple: with a selector like this, jQuery will have to check every element in your page before to return a result. You have two options to make this selector better: add a tag element, or add an ID before your class. If the tag element is a div, and you have plenty of div in your page, it will definitely help, but if you can get an id, pretty close to your class, you’ll be in a better shape!
$(‘#myID .myClass’).something(); //or $(‘ul.myClass’).something();
3. jQuery Variables and caching
If you read the second point then you now know how to select a DOM element pretty quickly and avoid wasting time with unnecessary checking of HTML elements. Which is great, but if you want to be even more efficient, what you want to do is to cache this selection in a variable so that you can reuse it without having to go through the whole jQuery checking process again. Let me show you an exemple:
$.each($(‘ul.myClass li’), function(){ if (this.id > 2) $(‘#foo’).something()
});
I used in my example a loop because it’s one of the main reason you should cache your variables. In that specific case, and even if we are using an ID to select an element, jQuery will still process the selection for each
- presents into your list. What you might want to do instead is:
var $foo = $(‘#foo’); $.each($(‘ul.myClass li’), function(){ if (this.id > 2) //random if, not even necessary $foo.something()
});
This time, the cached variable is used avoiding Jquery to waste time re-selecting the element every time you iterate inside your list. You should use this every time you need to call an element multiple times in your code (don’t create global variables for Jquery caching though, unless it’s really necessary). For the people using Backbone out there, when you are using this.$el or just $el, you’re actually using the cached version of the original el.
Using a cached variable is faster than any other options out there. For example doing $(this) or $(element) is still requiring jQuery to get the element inside you HTML Document.
4. jQuery Events
jQuery has seen a lot of different ways to bind an event to an element. The latest ones are .live(), .bind(), .delegate and .on(). A lot of people have wondered which one to use and why. The answer is simple: .on()!!
If you want to know why, the first thing you need to know is how Javascript events are working. So Google “javascript bubbling events” and take a class.
To give you the short answer in case Google is not your friend (we can’t like everybody, right?) here is what you should know:
When an event is triggered, it’s going through your entire DOM tree. By attaching an event handler to the document itself, listening to a click event on a child element, you’re handler will be triggered. This is what .live() does, in order to listen to event from elements that are not added yet to your DOM.
Since jQuery 1.7 the methods .live(), .bind() and .delegate() are implicitly calling the on() method of your jQuery. So the best thing for you and your team is to follow the latest way of implementing the events. You’ll get a full control on the way you are listening to events and make sure you’re not using more resources that you actually need.
The method .on() has multiple behaviors based on how you are declaring it:
The jQuery .bind(), .live(), and .delegate() methods are just one line pass throughs to the new jQuery 1.7 .on() method // Bind $( “#members li a” ).on( “click”, function( e ) {} ); $( “#members li a” ).bind( “click”, function( e ) {} ); // Live $( document ).on( “click”, “#members li a”, function( e ) {} ); $( “#members li a” ).live( “click”, function( e ) {} ); // Delegate $( “#members” ).on( “click”, “li a”, function( e ) {} );
$( “#members” ).delegate( “li a”, “click”, function( e ) {} );
5. jQuery custom Events
Sometimes while coding your web or mobile app, you might need to declare your own personal events. One of the classic situation is when a user login or logout. The fact that your user is pressing the logout button needs to refresh the UI of your app. One of the common ways to handle this is to use a custom event with jQuery. Here is how to do so:
Call or create a function when the user logout:
$.event.on(‘user:loggedOut’, function(data){ alert(data.name + ‘just logged out!’);
});
In this short example, notice the way you bind your app to an event, and the event name itself. Using namespaces for events makes your events management easier and more readable to you and your team. It also gives you the flexibility to define deeper events without messing up the overall app’s behavior. Take a look at the next example to understand the point:
$.event.on(‘user:professional:loggedOut’, function(data){ //much better than ‘userLoggedOut’ + test to identify the type of connected user, neater than proLoggedOut, jobseekerLoggedOut events alert(data.companyName + ‘just logged out of its workspace!’);
});
$.event.on(‘user:jobseeker:loggedOut’, loggedOut); var loggedOut = function(data){ alert(data.name + ‘just logged out!’);
};
The second argument can be a function already declared somewhere else, and the ‘data’ argument inside the callback is optional. It can be used to carry useful data and prevent you from polluting the global context.
Triggering your events:
$(‘#logoutBtn’).on(‘click’, function(){ //clear session and cookies, do stuff //if everything went OK, trigger the event. $.event.trigger(‘user:loggedOut’, app.user);
});
You can trigger your event at multiple locations within your app. You can also pass the data as the second argument.
To stop listening to an event: use $.event.off(‘user:loggedOut’). Be aware than running two times in a row the code above will make your function being called two times instead of one. So make sure that you’re declaring your events subscriptions when your app start and then don’t run the code again! (Unless it’s necessary)
6. HTML Manipulation
Modifying the content of a page in real time and avoid a refresh is one of the first purpose of jQuery. This section is to introduce some useful functions to modify your HTML without having to refresh your page.
$(‘ul#foo’).append($elem) : add an element at the end of the selection, $($elem).appendTo(‘ul#foo’) is equivalent $(‘ul#foo’).prepend($elem) : add an element at the beginning of the selection, $($elem).prependTo(‘ul#foo’) is equivalent $($elem).insertAfter(‘div.foo’) : insert the element after the selection $($elem).insertBefore(‘div.foo’) : insert the element before the selection $(‘li.button’).toggleClass(‘active’): add or remove the class ‘active’ to the selection
$(‘li.nav’).closest(‘a’): return the closest element from the selection $(‘#login’).toggle(): display or hide the element, optional parameters can be used like duration and callback function $(‘div.content’).empty(): empty the content of the selection, keep the selection in the DOM. $(‘#article1′).remove(): remove the selection and its content from the DOM. $(‘input#name’).attr(‘type’): get the value of the attribute ‘type’ $(‘input#name’).attr(‘type’, ‘text’): set the value of the attribute ‘type’ to ‘text’
$(‘input#name’).removeAttr(‘type’): remove the attribute ‘type’
7. jQuery Chaining
The chaining is a really powerful feature with jQuery. It provides a really neat way to set different actions/effects to be run on one element ordered by their position in the chain. It’s sounds complicated but it can be understood very easily with a simple example:
$($elem).hide().html(‘Hello World’).show(600); //equivalent to : $($elem).hide(); $($elem).html(‘Hello World’); $($elem).show(600);
The element is hidden, then its content becomes “Hello World” and finally it gets shown with the standard animation and a duration of 600ms.
Now let me show you an advanced example, you’ll realize how cool this can be and how you much power you get to create cool animations.
$($elem).fadeOut(500) //fade the selection .next() //select the next element .fadeIn(500) // fade the new selected element .end() //go back to the first selection
.remove() // remove it
I used this example to introduce another essential thing to know when using chaining: .end()
When used in a jQuery chaining .end is taking you back to ‘the first line’, understand: to the first selected element where our chaining has been initiated. Even if you call next() a few times, end() will take you back to the very first element. Notice also that by calling next(), I can apply the following functions on the newly selected element until I call end().
8. jQuery effects
Creating nice applications also means a great UX. Adding some effects to your application can be a big plus within your web app. jQuery provides basic but already powerful effects to apply to your HMTL page. Each effect has a callback function if needed.
.fadeOut(500): hide an element by fading it out of the screen. Pass it at least a duration .fadeIn(500): show an element by fading it in .slideUp(500): hide an element with a sliding up effect .slideDown(500): show an element with a sliding down effect .show(500): show an element from the top left to the bottom right. Need a duration to apply an effect. Different effects can be applied by passing parameters. .hide(500): hide an element from the bottom right to the top left. Same as show()
.animate()
The animate function allows you to play with css properties of the targeted object and animate the transition. This is equivalent to what CSS3 let you do but more compatible with old browsers. Look at the example below to understand how this works (you can chain multiple .animate() to get a step by step animation):
$(“#block”).animate({ width: “70%”, opacity: 0.4, marginLeft: “0.6in”, fontSize: “3em”, borderWidth: “10px” }, 1500, function(){ //Animation Complete
});
By using a framework like Twitter bootstrap or jQuery UI, you’ll get access to a lot of other cool effects like explode, slide left or right, bounce etc. It’s a great way to improve your UX. Google them and you’ll be happy to give your app more transition effects. If you are developing for mobile, take a look at jQuery mobile. It already has every standard effect a mobile app should require.
9. jQuery promises
Using $.Deferred
The jQuery promises are useful to manage async tasks. To easily understand it, you should think about your ajax calls. When one of them is done: if the server answers with a status 200, the success function is triggered, if not then the error function is called. The jQuery promises offer you the same possibility for any function in your code. You set a promise somewhere, and attach callbacks. Then you can decide how and when to call your success or error function by using .resolve() or .reject() inside your code. This basically means that you can asynchronously wait for something to be done, before to run another line of code, just like your AJAX calls!
To handle a promise, you’ll first need a deferred. Then from the deferred, you can change the state to resolve or rejected (success or error). You can get the promise from the deferred but it will be a read-only promise. You will need to use the deferred to set the promise’s state. Take a look at this example:
var deferred = new $.Deferred(); var promise = deferred.promise(); promise.state(); //return ‘pending’ deferred.reject(); //since your reject it, you won’t be able to change its state anymore. A promise has a one-time only state. promise.state(); // return ‘rejected’
promise.reject(); //return undefined, the promise is read-only
Attaching callbacks
Now you know how to define your promises states, but you need to attach callbacks to make it useful. The cool part is that you’re not limited in callbacks! You can easily call multiple functions when the promise is resolved. Let me show you how to do that:
promise.done(function() { // you could also use deferred.done() console.log(“This will run if this Promise is resolved.”); }); promise.done(function() { // will also be executed when the promise is resolved console.log(“This will run if this Promise is resolved.”); }); promise.fail(function() { // you could also use jQuery chaining here and do promise.done().fail()… console.log(“This will run if this Promise is rejected.”); }); promise.always(function() { console.log(“And this will run either way.”);
});
OR you could use .then() to attach them all in once:
promise.then(doneCallback, failCallback, alwaysCallback);
Handling multiple promises with .when()
The last but not least cool feature with promises is when you have to wait for multiple tasks to be done before to start a new interaction. It could be ressources to be preload before to load the content or multiple ajax calls.
when() is kind of like your AND in your conditional declaration. If the promises inside the when are all resolved, then the done callback is called, but if at least one of them failed, then the fail callback is called. Here is a good example:
var loadingChat = new $.Deferred(); yepnope({ load: “resources/chat.js”, complete: loadingChat.resolve }); var launchingChat = new $.Deferred(); $(“#launchChat”).click(launchingChat.resolve); launchingChat.done(function() {
$(“#chatContainer”).append(“
“); }); $.when(loadingChat, launchingChat).done(function() { // get called when the button has been clicked and the js file has been loaded $(“#chatContainer”).remove(“.spinner”); // start chat
});
The promises can also be pretty useful to wait for animations to be done. jQuery is pretty smart to resolve the promise by itself when a queue is successfully complete regarding animations. Take a look at that official page for more useful examples.
If you want to read a dedicated article about promises, visit this page.
10. jQuery Data Attributes
Storing data using data attribute in your HTML page is a great way to reduce the amount of ajax calls from your app to your servers. Storing information in the page itself using attributes named data-* (the HTML5 way) make them invisible to browsers and not interpreted and gives you a consequent freedom for your apps. Data-attributes are used more and more, from web app to mobile application and games developed using HTML5 and JavaScript. It allows the developers to store the transition’s style when a button is pressed, a type of icon to show, the experience required mastering a weapon…and it’s very easy to use! You can store strings, numbers and even json objects!
Check out the next example for a better understanding:
This is a typical link generated by jQuery mobile. The settings are stored with the data attributes, allowing the app to dynamically change its behavior per link without requiring you to write a jQuery function for each link and behavior (it will automatically use the internal generic function)!
Manipulate data attributes in your page is made super easy by the .data() function of jQuery. This function will take two parameters (the second one will be the value and is optional).
$(‘#foo’).data(‘role’); //will return button $(‘#foo’).data(‘role’, ‘page’) // will change the data-role attribute to ‘page’ $(‘#foo’).data(‘values’, { foo: ‘bar’, num: 12}); //will store the json object into data-values attribute $(‘#foo’).data(‘values’).num //will return the value inside your json : 12 (and not ’12′, .data() is trying to return the right value type)
$(‘#foo’).data( { baz: ‘foo’ }); //will add baz to the previous stored element (values)
If your attributes is named data-foo-bar=”something” then to getter and setter will use CamelCase like this: $(‘#foo’).data(‘fooBar’)
Data attributes were developed only to store custom data [about an element] when there is no more appropriate attribute or element available.
582 total views, 1 views today
Share this On