Uncovering jQuery’s Hidden Features
Tutorial Details
- Difficulty: Intermediate
- Technology: jQuery
jQuery is not always as it appears. There's a lot of cool stuff going on under the surface, and there are many methods just waiting to be discovered, and many potential usages of jQuery's API that you may not have considered before. In this article I'll be taking you through a few of the not-so-obvious things I've discovered about jQuery.
1. Understand jQuery!
When you call 'jQuery' what happens?
The jQuery function itself is very simple:
jQuery = function (selector, context) {
// The jQuery object is actually just the init constructor 'enhanced'
return new jQuery.fn.init(selector, context);
};
Under its skin, the jQuery function (commonly referred to as the "wrapper" function) simply returns an instantiated jQuery object — i.e. an instance of the 'jQuery.fn.init' constructor.
This is useful to know; with this information we know that each time we call 'jQuery' we're actually creating a totally unique object with a set of properties. jQuery is clever in that it gives you an object that can be treated as an array. Each of your elements (all together, commonly known as the "collection") is referenced within the object under a numerical index, just like within an array. And jQuery also gives this object a 'length' property, just as you would expect from an array. This opens up a world of possibilities. For one, it means that we can borrow some functionality from 'Array.prototype'. jQuery's 'slice' method is a good example of this — modified from the source:
/* ... jQuery.fn.extend({ ... */
slice: function() {
return this.pushStack(
Array.prototype.slice.apply( this, arguments ),
"slice",
Array.prototype.slice.call(arguments).join(",")
);
},
/* ... */
The native 'slice' method doesn't care that 'this' is not a real array– it'll be fine with anything that's got a 'length' property and [0], [1], [2] etc.
There are some other interesting properties within this jQuery object — '.selector' and '.context' will, most of the time, reflect the arguments that you pass into 'jQuery(…)'.
var jqObject = jQuery('a');
jqObject.selector; // => "a"
One thing that's important to note is that jQuery will sometimes give you new jQuery objects to work with. If you run a method that changes the collection in some way, such as '.parents()', then jQuery won't modify the current object; it'll simply pass you a brand new one:
var originalObject = jQuery('a');
var anotherObject = originalObject.parents();
originalObject === anotherObject; // => false
All methods that appear to mutate the collection in some way return a brand new jQuery object — you can still access the old object though, via '.end()', or more verbosely, via '.prevObject'.
2. Bread-and-butter Element Creation
Central to jQuery's DOM capabilities, is its element creation syntax. 1.4 brought with it an entirely new way to create your elements quickly and succinctly. E.g.
var myDiv = jQuery('<div/>', {
id: 'my-new-element',
class: 'foo',
css: {
color: 'red',
backgrondColor: '#FFF',
border: '1px solid #CCC'
},
click: function() {
alert('Clicked!');
},
html: jQuery('<a/>', {
href: '#',
click: function() {
// do something
return false;
}
})
});
As of 1.4 you can pass a second argument to the jQuery function when you're creating an element — the object you pass will, for the most part, act as if you were passing it to '.attr(…)'. However, jQuery will map some of the properties to its own methods, for example, the 'click' property maps to jQuery's 'click' method (which binds an event handler for the 'click' event) and 'css' maps to jQuery's 'css' method etc.
To check out what properties map to jQuery's methods, open your console and type 'jQuery.attrFn'.
3. Serialize your Inputs
jQuery provides a method that you can use to serialize all of the inputs within one or more forms. This is useful when submitting data via XHR ("Ajax"). It's been in jQuery for a long time but it's not often talked about and so many developers don't realise it's there. Submitting an entire form via Ajax, using jQuery, couldn't be simpler:
var myForm = $('#my-form');
jQuery.post('submit.php', myForm.serialize(), function(){
alert('Data has been sent!');
});
jQuery also provides the 'serializeArray' method, which is designed to be used with multiple forms, and the 'param' helper function (under the jQuery namespace) which takes a regular object and returns a query string, e.g.
var data = {
name: 'Joe',
age: 44,
profession: 'Web Developer'
};
jQuery.param(data); // => "name=Joe&age=44&profession=Web+Developer"
4. Animate Anything
jQuery's 'animate' method is probably the most flexible of jQuery's methods. It can be used to animate pretty much anything, not just CSS properties, and not just DOM elements. This is how you would normally use 'animate':
jQuery('#box').animate({
left: 300,
top: 300
});
When you specify a property to animate (e.g. 'top') jQuery checks to see if you're animating something with a style property ('element.style'), and it checks if the specified property ('top') is defined under 'style' — if it's not then jQuery simply updates 'top' on the element itself. Here's an example:
jQuery('#box').animate({
top: 123,
foo: 456
});
'top' is a valid CSS property, so jQuery will update 'element.style.top', but 'foo' is not a valid CSS property, so jQuery will simply update 'element.foo'.
We can use this to our advantage. Let's say, for example, that you want to animate a square on a canvas. First let's define a simple constructor and a 'draw' method that'll be called on every step of the animation:
function Square(cnvs, width, height, color) {
this.x = 0;
this.y = 0;
this.width = width;
this.height = height;
this.color = color;
this.cHeight = cnvs.height;
this.cWidth = cnvs.width;
this.cntxt = cnvs.getContext('2d');
}
Square.prototype.draw = function() {
this.cntxt.clearRect(0, 0, this.cWidth, this.cHeight);
this.cntxt.fillStyle = this.color;
this.cntxt.fillRect(this.x, this.y, this.width, this.height);
};
We've created our 'Square' constructor, and one of its methods. Creating a canvas and then animating it couldn't be simpler:
// Create a <canvas/> element
var canvas = $('<canvas/>').appendTo('body')[0];
canvas.height = 400;
canvas.width = 600;
// Instantiate Square
var square = new Square(canvas, 70, 70, 'rgb(255,0,0)');
jQuery(square).animate({
x: 300,
y: 200
}, {
// 'draw' should be called on every step
// of the animation:
step: jQuery.proxy(square, 'draw'),
duration: 1000
});
This is a very simple effect, but it does clearly demonstrate the possibilities. You can see it in action here: http://jsbin.com/ocida (this will only work in browsers that support the HTML5 canvas)
5. jQuery.ajax Returns the XHR Object
jQuery's Ajax utility functions ('jQuery.ajax', 'jQuery.get', 'jQuery.post') all return an 'XMLHttpRequest' object which you can use to perform subsequent operations on any request. For example:
var curRequest;
jQuery('button.makeRequest').click(function(){
curRequest = jQuery.get('foo.php', function(response){
alert('Data: ' + response.responseText);
});
});
jQuery('button.cancelRequest').click(function(){
if (curRequest) {
curRequest.abort(); // abort() is a method of XMLHttpRequest
}
});
Here we're making a request whenever the 'makeRequest' button is clicked — and we're cancelling the active request if the user clicks the 'cancelRequest' button.
Another potential usage is for synchronous requests:
var myRequest = jQuery.ajax({
url: 'foo.txt',
async: false
});
console.log(myRequest.responseText);
Read more about the 'XMLHttpRequest' object and also be sure to check out jQuery's Ajax utilities.
6. Custom Queues
jQuery has a built-in queuing mechanism that's used by all of its animation methods (all of which use 'animate()' really). This queuing can be illustrated easily with a simple animation:
jQuery('a').hover(function(){
jQuery(this).animate({paddingLeft:'+=15px'});
}, function(){
jQuery(this).animate({paddingLeft:'-=15px'});
});
Quickly hovering over a bunch of anchors and then hovering over them again will cause the animations to queue up and occur one at a time — I'm sure many of you have witnessed this queuing effect before. If not, check it out here: http://jsbin.com/aqaku
The 'queue' method is similar to the well-known 'each' method in how it's called. You pass a function, which will eventually be called for each of the elements in the collection:
jQuery('a').queue(function(){
jQuery(this).addClass('all-done').dequeue();
});
Passing just a function to 'queue' will cause that function to be added to the default 'fx' queue, i.e. the queue used by all animations done by jQuery. Therefore, this function will not be called until all current animations occurring on each element in the collection (in this case, all anchors) have completed.
Notice that we're adding a class of 'all-done' in the function above. As outlined, this class will only be added when all current animations are complete. We're also calling the 'dequeue' method. This is very important, as it will allow jQuery to continue with the queue (i.e. it lets jQuery know that you're finished with whatever you're doing). jQuery 1.4 provides another way of continuing the queue; instead of calling 'dequeue', simply call the first argument passed to your function:
jQuery('a').queue(function(nextItemInQueue){
// Continue queue:
nextItemInQueue();
});
This does exactly the same, although it's slightly more useful in that it can be called anywhere within your function, even within a mess of closures (that typically destroy the 'this' keyword). Of course, pre-jQuery-1.4 you could just save a reference to 'this', but that would get a bit tiresome.
To add a function to a custom queue, simply pass your custom queue's name as the first argument and the function as the second:
jQuery('a').queue('customQueueName', function(){
// Do stuff
jQuery(this).dequeue('customQueueName');
});
Notice that, since we're not using the default 'fx' queue, we also have to pass our queue's name to the 'dequeue' method, in order to allow jQuery to continue with our custom queue.
Read more about 'queue', 'dequeue' and 'jQuery.queue'.
7. Event Namespacing
jQuery provides a way for you to namespace events, which can be very useful when authoring plugins and third-party components. If needed, the user of your plugin can effectively disable your plugin by unbinding all event handlers that it's registered.
To add a namespace when registering an event handler, simply suffix the event name with a period and then your unique namespace (e.g. '.fooPlugin'):
jQuery.fn.foo = function() {
this.bind('click.fooPlugin', function() {
// do stuff
});
this.bind('mouseover.fooPlugin', function() {
// do stuff
});
return this;
};
// Use the plugin:
jQuery('a').foo();
// Destroy its event handlers:
jQuery('a').unbind('.fooPlugin');
Passing just the namespace to 'unbind' will unbind all event handlers with that namespace.
Conclusion
So which ones did I miss? Any helpful features that you feel jQuery doesn’t document well enough? Let’s discuss in the comments!





RoyalSlider – Touch-Enable ... only $12.00 
Wow. Really nice…
Yh, shame i suck at coding
I wish i would have known about some of these before, thank you great article!.
First…
Thank you…….
Why do you need to say: “First”? Always a spammer is looking to be the first to promote his blog. I’m 100% sure that he didn’t read this post.
@Mladen: Just as sure as I am you didn’t read the post either. Instead you just scrolled to the comments looking for one particular comment that you can reply to and criticize the OP, thus causing a spiral of back-and-forth bickering between visitors all for your amusement and … wait a minute … It’s a fair cop!
@Mr. Padolsey, great article though sir. I’ve only known how to use jQuery in my scripts. This has helped me to understand why this function does this, and that function does that. Maybe with time you might consider Vladimir’s suggestion below? I would definitely renew my Plus membership to see that (because no doubt it would fall under classification of a Plus tutorial).
Cheers!
- AP
Yup, you got me. :(
#Mladen : WoW, your mind is very bad. I write like that because I do not see the other commentators above me. What’s wrong if I say it like that? I read this article, and learned a lot from this site. I also follow this site via twitter and FeedReader. Please do not accuse. Huh.
As someone who used to do this practice (comment first, whatever the comment is), I really wonder what the benefit I have gained (other than few no-follow back links). Only the stupid and mindless visitors will be hitting your blog for few seconds. Happy to see some additional visitors to your site?
If you are addict to your site stat, then just remove the Google analytics code.
If you like the article, retweet it, if you found it useful, then try to build, polish some work with it. If you have a useful suggestion or found a bug, then your comment will become invaluable, otherwise it’s pure SPAM and shit.
Great comment Omar!
@izulcybercafe, “WoW, your mind is very bad. I write like that because I do not see the other commentators above me.” better refresh the page before commenting.
What’s wrong if I say it like that?wrong, because you are Not the first.
“I read this article, and learned a lot from this site.” and you should learn how to comment, good article from your view point worth good comment from you, right?
Second …
Thank you very much …..
Excellent !
this is why i like nettuts, we get to understand things rather copying tutorial code
always been a fan of james
Great tutorial.
I have one suggestion for the @James and @Nettuts. I think the we are all missing the most important tutorial for jQuery and that is someone who is able to explain the core.js of jQuery.
I know it is little advanced topic but I think we all love to learn how JQuery really works. So, please consider writing core jQuery architecture tutorial.
Thanks
Vladimir, I would agree completely. It would be an incredibly advanced tutorial, but it would uncover some of the best JavaScript programming techniques used today. John Resig did a good job of revealing some of these techniques in his book Pro JavaScript Techniques, and I believe even more will be revealed in Secrets of the JavaScript Ninja. If you’re interested in knowing how jQuery works behind the scenes, then I recommend both books.
@Brian: I’m waiting for that book more than one year, hopefully this summer “Secrets of the JavaScript Ninja” will be out.
I agree as well. I’d also really like to see a ‘Develop a Custom Javascript Framework’ series to take you through the basics of what goes into designing and building a framework. Not to be used as a serious alternative to the major libraries necessarily, but I think it would really help people to more fully understand the frameworks they use and the decisions that go into developing them.
If you are talking about Javascript Ninja from Manning Publications, you probably don’t have to wait, can read this book as it is being written through Manning’s early access programme.
Nice! Thanks for the tips. Did not know about the async Ajax option.
Very good article. Opened up my mind to many cool possibilities.
Keep em’ coming!
WOW.. thanks you great article!.
I wish i had known about some of these before, would have saved some time.
Great article. Thanks!
Thanks for the great tips. It always seems like jQuery is even more useful than I know. I appreciate the depth of the library. Thanks for sharing.
The serialization and the XMLHttpRequest information is something Ill definitely put into practice. Thanks for the clear explanation.
Ditto to that James!
Really appreciate this jQuery tut. It helps me to really think through the code rather than just memorize what each method does. I am trying to learn core Javascript so that this process becomes even easier. Really been enjoying your Javascript and the DOM tuts from awhile back to James. Thanks!
You can pass an object map of events…
jQuery.fn.foo = function() {
this.bind({
click.fooPlugin: function() {
// do stuff
},
mouseover.fooPlugin: function() {
// do stuff
}
});
return this;
};
james padolsey is the man when it comes to jquery ….
love the serializing in jquery btw.
Now this was interesting to read, thank you.
Very nice article and very useful information :) some of them well known and some of them nice to know from now :)
Thanks..
interesting read..!
jQuery teach more than year, but about these tricks read in the first time. I will test, especially as already there are the my small projects with jQuery. Thanks.
Well for me the serialize method was like really giving me some bad memories. God how the hell was i not thinking about this.
Thanks for the great article.
~Razvan
Very sick tutorial.
Thanks
Wht are you using in your code? What does it ?
Very Nice explaining. This helped a lot, and i’m even a beginner at Jquery.
This is a clear and well written tutorial on some of the advanced features of jQuery.
Excellent starting point to dive into jQuery.
jQuery is just ingenious.
Thanks for posting this.
It’s really useful.
Marv. Thanks.
Nice information about Jquery it is
I definitely wasn’t aware of the serialize() functionality. So thanks for that!
Thanks for this post, it’s great! I think the new element creation feature in 1.4 is amazing.
Excellent article. I use Event Namespacing, XHR and Serialization all the time but Custom Queues is new to me. Very handy.
Keep them coming James. Would like to see more jQuery articles on Nettuts.
nice post !!! thank you for sharing it …
Great tips. The que method can really make your complex scripts more stable.
Great read !!!… thanks a bunch James :)
Why are you using within the code snippets ???
I mean the tags: <wbr>
These are all great. Thanks for putting it together.
There is a bug in #2 Bread-and-butter Element Creation:
class: ‘foo’, should be className: ‘foo’,
class seems to work fine in Firefox but in Safari or IE it gives a parser error. Using className fixes the issue.
nice ones…
Thanks very informative.
I would like also to share this.
$.myPlugin = {‘version’: 1.0};
$.fn.myPlugin = function(){
//plugin code
//inside this code you can create global function for your plugin
$.myPlugin.myfunction(){
//functions code
}
}
So you can do something like this.
$(‘selector’).myPlugin();
$.myPlugin.myfunction();
Nice article … never thought that jquery would become so strong.
Been using it for some time now…. saved me a lot of time.
Nice article.
Got to know so many things that was already there and I didn’t know.
One thing I’ve noticed recently and have been using:
You can directly pass a json object to the data parameter of $.ajax, it does not need to be a query string
<pre name=”js”>
var qstring = {cmd:”changepwd”,oldpwd:”XXXXX”,newpwd:”VVVVV”};
$.ajax({type:”post”,data:qstring,url:”XHR.php”,success:function(d){console.log(d)}});
</pre>
Just thought might be helpful to someone :)