Practical example of need for prototypal inheritance
Alex Sexton wrote a wonderful article about how to use inheritance pattern to manage large piece of code. His code also has a pratical need for prototypal inheritance for writing modular code.
creating standard jQuery plugin
Given below is code that does exactly what Alex’s code does.
$(function() {
$.fn.speaker = function(options) {
if (this.length) {
return this.each(function() {
var defaultOptions = {
name: 'No name'
};
options = $.extend({},
defaultOptions, options);
var $this = $(this);
$this.html('<p>' + options.name + '</p>');
var fn = {};
fn.speak = function(msg) {
$this.append('<p>' + msg + '</p>' );
};
$.data(this, 'speaker', fn);
});
}
};
});
For smaller plugins this code is not too bad. However if the plugin is huge then it presents one big problem. The code for business problem and the code that deals with jQuery is all mixed in. What it means is that if tomorrow same functionality needs to be implemented for Prototype framework then it is not clear what part of code deals with framework and what part deals with business logic.
Separating business logic and framework code
Given below is code that separates business logic and framework code.
var Speaker = function(opts, elem) {
this._build = function() {
this.$elem.html('<h1>' + options.name + '</h1>');
};
this.speak = function(msg) {
this.$elem.append('<p>' + msg + '</p>');
};
var defaultOptions = {
name: 'No name'
};
var options = $.extend({},
defaultOptions, this.opts);
this.$elem = $(elem);
this._build();
};
$(function() {
$.fn.speaker = function(options) {
if (this.length) {
return this.each(function() {
var mySpeaker = new Speaker(options, this);
$.data(this, 'speaker', mySpeaker);
});
}
};
});
This code is an improvement over first iteration. However the whole business logic is captured inside a function. This code can be further improved by embracing object literal style of coding.
Final Improvement
Third and final iteration of the code is the code presented by Alex.
var Speaker = {
init: function(options, elem) {
this.options = $.extend({},
this.options, options);
this.elem = elem;
this.$elem = $(elem);
this._build();
},
options: {
name: "No name"
},
_build: function() {
this.$elem.html('<h1>' + this.options.name + '</h1>');
},
speak: function(msg) {
this.$elem.append('<p>' + msg + '</p>');
}
};
// Make sure Object.create is available in the browser (for our prototypal inheritance)
if (typeof Object.create !== 'function') {
Object.create = function(o) {
function F() {}
F.prototype = o;
return new F();
};
}
$(function() {
$.fn.speaker = function(options) {
if (this.length) {
return this.each(function() {
var mySpeaker = Object.create(Speaker);
mySpeaker.init(options, this);
$.data(this, 'speaker', mySpeaker);
});
}
};
Notice the Object.create patten Alex used. The business logic code was converted from a function to a JavaScript object. However the problem is that you can’t create a new on that object. And you need to create new object so that you could dole out new objects to each element. Object.create pattern comes to rescue. This pattern takes a standard Object and returns an instane of a function. This function has the input object set as prototype. So you get a brand new object for each element and you get to have all your business logic in object literal way and not in a function. If you want to know more about prototypal inheritance then you can read my previous blog .
Object.create is now part of ECMAScript 5 .
prototypal inheritance in JavaScript
One of the key features of JavaScript language is its support for prototype method. This feature could be used to bring inheritance in JavaScript.
In the beginning there was duplication
function Person(dob){
this.dob = dob;
this.votingAge = 21;
}
function Developer(dob, skills){
this.dob = dob;
this.skills = skills || '';
this.votingAge = 21;
}
// create a Person instance
var person = new Person('02/02/1970');
//create a Developer instance
var developer = new Developer('02/02/1970', 'JavaScript');
As you can see both Person and Developer objects have votingAge property. This is code duplication. This is an ideal case where inheritance can be used.
prototype method
Whenever you create a function, that function instantly gets a property called prototype. The initial value of this prototype property is empty JavaScript object {} .
var fn = function(){};
fn.prototype //=> {}
JavaScript engine while looking up for a method in a function first searches for method in the function itself. Then the engine looks for that method in that functions’ prototype object.
Since prototype itself is a JavaScript object, more methods could be added to this JavaScript object.
var fn = function(){};
fn.prototype.author_name = 'John';
var f = new fn();
f.author_name; //=> John
Refactoring code to make use of prototype method
Currently Person function is defined like this.
function Person(dob){
this.dob = dob;
this.votingAge = 21;
}
Problem with above code is that every time a new instance of Person is created, two new properties are created and they take up memory. If a million objects are created then all instances will have a property called votingAge even though the value of votingAge is going to be same. All the million person instances can refer to same votingAge method if that method is define in prototype. This will save a lot of memory.
function Person(dob){
this.dob = dob;
}
Person.prototype.votingAge = 21;
The modified solutions will save memory if a lot of objects are created. However notice that now it will a bit longer for JavaScript engine to look for votingAge method. Previously JavaScript engine would have looked for property named votingAge inside the person object and would have found it. Now the engine will not find votingAge property inside the person object. Then engine will look for person.prototype and will search for votingAge property there. It means, in the modified code engine will find votingAge method in the second hop instead of first hop.
Bringing inheritance using prototype property
Currently Person is defined like this.
function Person(dob){
this.dob = dob;
}
Person.prototype.votingAge = 21;
If Developer Object wants to extend Person then all that needs to be done is this.
function Developer (dob, skills) {
this. skills = skills || '';
this.dob = dob;
}
Developer.prototype = new Person();
Now Developer instance will have access to votingAge method. This is much better. Now there is no code duplication between Developer and Person.
However notice that looking for votingAge method from a Developer instance will take an extra hop.
- JavaScript engine will first look for votingAge property in the Developer instance object.
- Next engine will look for votingAge property in its prototype property of Developer instance which is an instance of Person. votingAge method is not declared in the Person instance.
- Next engine will look for votingAge property in the prototype of Person instance and this method would be found.
Since only the methods that are common to both Developer and Person are present in the Person.prototype there is nothing to be gained by looking for methods in the Person instance. Next implementation will be removing the middle man.
Remove the middle man
Here is the revised implementation of Developer function.
function Developer (dob, skills) {
this.skills = skills || '';
this.dob = dob;
}
Developer.prototype = Person.prototype;
In the above case Developer.prototype directly refers to Person.prototype. This will reduce the number of hops needed to get to method votingAge by one compared to previous case.
However there is a problem. If Developer changes the common property then instances of person will see the change. Here is an example.
Developer.prototype.votingAge = 18;
var developer = new Developer('02/02/1970', 'JavaScript');
developer.votingAge; //=> 18
var person = new Person();
person.votingAge; //=> 18. Notice that votingAge for Person has changed from 21 to 18
In order to solve this problem Developer.prototype should point to an empty object. And that empty object should refer to Person.prototype .
Solving the problem by adding an empty object
Here is revised implementation for Developer object.
function Developer(dob, skills) {
this.dob = dob;
this.skills = skills;
}
var F = function(){};
F.prototype = Person.prototype;
Developer.prototype = new F();
Let’s test this code.
Developer.prototype.votingAge = 18;
var developer = new Developer('02/02/1970', 'JavaScript');
developer.votingAge; //=> 18
var person = new Person();
person.votingAge; //=> 21
As you can see with the introduction of empty object, Developer instance have votingAge of 18 while Person intances have votingAge of 21.
Accessing super
If child wants to access super object then that should be allowed. That can be accomplished like this.
function Person(dob){
this.dob = dob;
}
Person.prototype.votingAge = 21;
function Developer(dob, skills) {
this.dob = dob;
this.skills = skills;
}
var F = function(){};
F.prototype = Person.prototype;
Developer.prototype = new F();
Developer.prototype.__super = Person.prototype;
Developer.prototype.votingAge = 18;
Capturing it as a pattern
The whole thing can be captured in a helper method that would make it simple to create inheritance.
var extend = function(parent, child){
var F = function(){};
F.prototype = parent.prototype;
child.prototype = new F();
child.prototype.__super = parent.prototype;
};
Pure prototypal inheritance
A simpler form of pure prototypal inheritance can be structured like this.
if (typeof Object.create !== 'function') {
Object.create = function (o) {
function F() {}
F.prototype = o;
return new F();
};
}
Before adding the create method to object, I checked if this method already exists or not. That is important because Object.create is part of ECMAScript 5 and slowly more and more browsers will start adding that method natively to JavaScript.
You can see that Object.create takes only one parameter. This method does not necessarily create a parent child relationship . But it can be a very good tool in converting an object literal to a function.
return false considered harmful in live
Checkout following jQuery code written with jQuery.1.4.2. What do you think will happen when first link is clicked.
$('a:first').live('click', function(){
log('clicked once');
return false;
});
$('a:first').live('click', function(){
log('clicked twice');
return false;
});
I was expecting that I would see both the messages. However jQuery only invokes the very first message.
return false does two things. It stops the default behavior which is go and fetch the link mentioned in the
href of the achor tags. Also it stops the event from bubbling up. Since live method relies on event bubbling, it makes sense that second message does not appear.
Fix is simple. Just block the default action but let the event bubble up.
$('a:first').live('click', function(e){
log('clicked once');
e.preventDefault();
});
$('a:first').live('click', function(e){
log('clicked twice');
e.preventDefault();
});
Simplest jQuery slideshow code explanation
Jonathan Snook wrote a blog titled Simplest jQuery SlideShow . Checkout the demo page .
The full JavaScript code in its entirety is given below. If you understand this code then you don’t need to read rest of the article.
$(function(){
$('.fadein img:gt(0)').hide();
setInterval(function(){
$('.fadein :first-child').fadeOut()
.next('img').fadeIn()
.end().appendTo('.fadein');},
3000);
});
appendTo removes and attaches elements
In order to understand what’s going on above, I am constructing a simple test page. Here is the html markup.
<div id='container'> <div class='lab'>This is div1 </div> <div class='lab'>This is div2 </div> </div>
Open this page in browser and execute following command in firebug.
$('.lab:first').appendTo('#container');
Run the above command 5/6 times to see its effect. Every single time you run JavaScript the order is changing.
The order of div elements with class lab is changing because if a jQuery element is already part of document and that element is being added somewhere else then jQuery will do cut and paste and not copy and paste . Again elements that already exist in the document get plucked out of document and then they are inserted somewhere else in the document.
Back to original problem
In the original code the very first image is being plucked out of document and that image is being added to set again. In simpler terms this is what is happening. Initially the order is like this.
Image1 Image2 Image3
After the code is executed the order becomes this.
Image2 Image3 Image1
After the code is executed again then the order becomes this.
Image3 Image1 Image2
After the code is executed again then the order becomes this.
Image1 Image2 Image3
And this cycle continues forever.
Build a google chrome extension using jQuery
Lately I have been following jQuery commits on github . If I look at a commit which fixes a bug then I would like to go and see the bug description. In order to do that I need to type url which would be something like this http://dev.jquery.com/ticket/6084 .
I wrote a chrome extension which would add a link to the bug at the end of commit message.
Install the extension and try it
The extension is available here . After installing the extension visit this page and you should see a link at the end of commit message.
Developing the extension and packaging it
Developing an extension on google chrome is very simple.
- git clone the source code of my extension or create file structure similar to this
- Zip the folder contents and create jQueryBugLink.zip
- Visit chrome.google.com/extensions and click on publish your extensions
- Upload the zip file and publish your extension
That’s it.
Unit Testing JavaScript using Qunit . See live result and test code
If you are in a hurry then take a look at these two links and you are done.
Introduction
Six months ago I wrote about JavaScript testing using blue-ridge, Screw.Unit, env.js and Rhino . Since then I have changed my thoughts about JavaScript testing in fundamental ways and I do not recommend writing JavaScript unit tests that would not run on an actual browser.
I could never do as good a job as Nicholas did on his blog on capturing thoughts on JavaScript unit testing. I agree with him 100%.
Since I do not recommend using rhino, what I do recommend. I like Qunit .
Getting started
Sometimes getting started is the most difficult part. There are lot of JavaScript testing tools in the market and the documentation of most of them show simple case of testing 2 + 2. That is not very helpful.
The good thing with Qunit is that if you ever want to see how to use Qunit then just look at the test code of jQuery. At the bottom of this page you will find links of other projects that user Qunit to write tests.
I don not want to look at jQuery test code. I use ruby on rails and I just want to get started
For my admin_data plugin I wrote a bunch of JavaScript tests . Take a look at them to get a feel for how to use Qunit for you ruby on rails application. Get the code from github and you can play with JavaScript test code.
Click here to see the test result for the tests written for admin_data. I have tested this test page with Firefox, Chrome, Safari, IE 6, IE 7 and IE 8 .
How jQuery selects elements using Sizzle
Introduction
jQuery’s motto is to select something and do something with it. As jQuery users, we provide the selection criteria and then we get busy with doing something with the result. This is a good thing. jQuery provides extermely simple API for selecting elements. If you are selecting ids then just prefix the name with ‘#’. If you are selecting a class then prefix it with ‘.’.
However it is important to understand what goes on behind the scene for many reasons. And one of the important reasons is the performance of Rich Client. As more and more web pages use more and more jQuery code, understanding of how jQuery selects elements will speed up the loading of pages.
What is a selector engine
HTML documents are full of html markups. It’s a tree like structure. Ideally speaking all the html documents should be 100% valid xml documents. However if you miss out on closing a div then browsers forgive you ( unless you have asked for strict parsing). Ultimately browser engine sees a well formed xml document. Then the browser engine renders that xml on the browser as a web page.
After a page is rendered then those xml elements are referred as DOM elements.
JavaScript is all about manipulating this tree structure (DOM elements) that browser has created in memory. A good example of manipulating the tree is command like the one give below which would hide the header element. However in order to hide the header tag, jQuery has to get to that DOM element.
jQuery('#header').hide()
The job of a selector engine is to get all the DOM elements matching the criteria provided by a user. There are many JavaScript selector engines in the market. Paul Irish has a nice article about JavaScript CSS Selector Engine timeline .
Sizzle is JavaScript selector engine developed by John Resig and is used internally in jQuery. In this article I will be showing how jQuery in conjunction with Sizzle finds elements.
Browsers help you to get to certain elements
Browsers do provide some helper functions to get to certain types of elements. For example if you want to get DOM element with id header then document.getElementById function can be used like this
document.getElementById('header')
Similarly if you want to collect all the p elements in a document then you could use following code .
document.getElementsByTagName('p')
However if you want something complex like the one given below then browsers were not much help. It was possible to walk up and down the tree however traversing the tree was tricky because of two reasons: a) DOM spec is not very intuitive b) Not all the browsers implemented DOM spec in same way.
jQuery('#header a')
Later selector API came out.
The latest version of all the major browsers support this specification including IE8. However IE7 and IE6 do not support it. This API provides querySelectorAll method which allows one to write complex selector query like document.querySelectorAll(“#score>tbody>tr>td:nth-of-type(2)” .
It means that if you are using IE8 or current version of any other modern browser then jQuery code jQuery(‘#header a’) will not even hit Sizzle. That query will be served by a call to querySelectorAll .
However if you are using IE6 or IE7, Sizzle will be invoked for jQuery(‘#header a’). This is one of the reasons why some apps perform much slower on IE6/7 compared to IE8 since a native browser function is much faster then elements retrieval by Sizzle.
Selection process
jQuery has a lot of optimization baked in to make things run faster. In this section I will go through some of the queries and will try to trace the route jQuery follows.
$(‘#header’)
When jQuery sees that the input string is just one word and is looking for an id then jQuery invokes document.getElementById . Straight and simple. Sizzle is not invoked.
$(‘#header a’) on a modern browser
f the browser supports querySelectorAll then querySelectorAll will satisfy this request. Sizzle is not invoked.
$(‘.header a[href!=“hello”]’) on a modern browser
In this case jQuery will try to use querySelectorAll but the result would be an exception (atleast on firefox). The browser will throw an exception because the querySelectorAll method does not support certain selection criteria. In this case when browser throws an exception, jQuery will pass on the request to Sizzle. Sizzle not only supports css 3 selector but it goes above and beyond that.
$(‘.header a’) on IE6/7
On IE6/7 querySelectorAll is not available so jQuery will pass on this request to Sizzle. Let’s see a little bit in detail how Sizzle will go about handling this case.
Sizzle gets the selector string ‘.header a’. It splits the string into two parts and stores in variable called parts.
parts = ['.header', 'a']
Next step is the one which sets Sizzle apart from other selector engines. Instead of first looking for elements with class header and then going down, Sizzle starts with the outer most selector string. As per this presentation from Paul Irish YUI3 and NWMatcher also go right to left.
So in this case Sizzle starts looking for all a elements in the document. Sizzle invokes the method find. Inside the find method Sizzle attempts to find out what kind of pattern this string matches. In this case Sizzle is dealing with string a .
Here is snippet of code from Sizzle.find .
match: {
ID: /#((?:[\w\u00c0-\uFFFF-]|\\.)+)/,
CLASS: /\.((?:[\w\u00c0-\uFFFF-]|\\.)+)/,
NAME: /\[name=['"]*((?:[\w\u00c0-\uFFFF-]|\\.)+)['"]*\]/,
ATTR: /\[\s*((?:[\w\u00c0-\uFFFF-]|\\.)+)\s*(?:(\S?=)\s*(['"]*)(.*?)\3|)\s*\]/,
TAG: /^((?:[\w\u00c0-\uFFFF\*-]|\\.)+)/,
CHILD: /:(only|nth|last|first)-child(?:\((even|odd|[\dn+-]*)\))?/,
POS: /:(nth|eq|gt|lt|first|last|even|odd)(?:\((\d*)\))?(?=[^-]|$)/,
PSEUDO: /:((?:[\w\u00c0-\uFFFF-]|\\.)+)(?:\((['"]?)((?:\([^\)]+\)|[^\(\)]*)+)\2\))?/
},
One by one Sizzle will go through all the match definitions. In this case since a is a valid tag, a match will be found for TAG. Next following function will be called.
TAG: function(match, context){
return context.getElementsByTagName(match[1]);
}
Now result consists of all a elements.
Next task is to find if each of these elements has a parent element matching .header. In order to test that a call will be made to method dirCheck. In short this is what the call looks like.
dir = 'parentNode'; cur = ".header" checkSet = [ a www.neeraj.name, a www.google.com ] // object representation dirCheck( dir, cur, doneName, checkSet, nodeCheck, isXML )
dirCheck method returns whether each element of checkSet passed the test. After that a call is made to method preFilter. In this method the key code is below
if ( not ^ (elem.className && (" " + elem.className + " ").replace(/[\t\n]/g, " ").indexOf(match) >= 0) )
For our example this is what is being checked
" header ".indexOf(" header ")
This operation is repeated for all the elements on the checkSet. Elements not matching the criteria are rejected.
More methods in Sizzle
if you dig more into Sizzle code you would see functions defined as +, > and ~ . Also you will see methods like
enabled: function(elem){
return elem.disabled === false && elem.type !== "hidden";
},
disabled: function(elem){
return elem.disabled === true;
},
checked: function(elem){
return elem.checked === true;
},
selected: function(elem){
elem.parentNode.selectedIndex;
return elem.selected === true;
},
parent: function(elem){
return !!elem.firstChild;
},
empty: function(elem){
return !elem.firstChild;
},
has: function(elem, i, match){
return !!Sizzle( match[3], elem ).length;
},
header: function(elem){
return /h\d/i.test( elem.nodeName );
},
text: function(elem){
return "text" === elem.type;
},
radio: function(elem){
return "radio" === elem.type;
},
checkbox: function(elem){
return "checkbox" === elem.type;
},
file: function(elem){
return "file" === elem.type;
},
password: function(elem){
return "password" === elem.type;
},
submit: function(elem){
return "submit" === elem.type;
},
image: function(elem){
return "image" === elem.type;
},
reset: function(elem){
return "reset" === elem.type;
},
button: function(elem){
return "button" === elem.type || elem.nodeName.toLowerCase() === "button";
},
input: function(elem){
return /input|select|textarea|button/i.test(elem.nodeName);
}
},
first: function(elem, i){
return i === 0;
},
last: function(elem, i, match, array){
return i === array.length - 1;
},
even: function(elem, i){
return i % 2 === 0;
},
odd: function(elem, i){
return i % 2 === 1;
},
lt: function(elem, i, match){
return i < match[3] - 0;
},
gt: function(elem, i, match){
return i > match[3] - 0;
},
nth: function(elem, i, match){
return match[3] - 0 === i;
},
eq: function(elem, i, match){
return match[3] - 0 === i;
}
I use all these methods almost daily and it was good to see how these methods are actually implemented.
Performance Implications
Now that I have little more understanding of how Sizzle works, I can better optimize my selector queries. Here are two selectors doing the same thing.
$('p.about_me .employment');
$('.about_me p.employment');
Since Sizzle goes from right to left, in the first case Sizzle will pick up all the elements with the class employment and then Sizzle will try to filter that list. In the second case Sizzle will pick up only the p elements with class employment and then it will filter the list. In the second case the right most selection criteria is more specific and it will bring better performance.
So the rule with Sizzle is to go more specific on right hand side and to go less specific on left hand side. Here is another example.
$('.container :disabled');
$('.container input:disabled');
The second query will perform better because the right side query is more specific.
Inject for array
Inject is awesome. I was going through comments of this blog and learned something new today.
Given below is a case where I need to add all the numbers. One way to solve would be something like this.
ar = [[:a, 1], [:b, 2], [:c, 3]] c = ar.inject(0) do |sum, record| sum += record[1] end puts c #=> 6
Here is another way to solve the same problem.
ar = [[:a, 1], [:b, 2], [:c, 3]] d = ar.inject(0) do |sum, (first, second)| sum += second end puts d
The second parameter in the block is split based on pattern. If the inner array has three elements then all the three elements can be split based on pattern.
ar = [[:a, 1, 11], [:b, 2, 22], [:c, 3, 33]] d = ar.inject(0) do |sum, (first, second, third)| sum += third end puts d #=> 66
DOMLint
I have seen JSLint , JavaScript Lint , JSON Lint and jQuery Lint .
Today I came across DOM Lint in this jQuery thread .
I never really thought it before but what if the name of a form is getElementById.
<form name="getElementById">
...
</form>
How about addEventListener as the id of a div.
<div id="addEventListener"> ... </div>
I am quoting Dave here. He explained the problem very well.
I strongly recommend against using using name/id attributes that are identical to the elements or properties. Specifically, don’t name an input element “select”, “id”, “name”, “form”, “action”, “method”, “value”, or any other name that is documented to be used by form or input elements. Here is why. The form element allows you to access its inputs by saying formname.inputname. So if you have an input named “myinput” you can use form.myinput to access it. But what if you name an input “id”? Now when you say form.id do you mean the “id” property of the form, or do you mean the “id” input inside the form?
If you run into those cases then you can use DOMLint . Source code is on github and here is the initial announcement .
Understanding jQuery effects queue
Recently I tried following code in jQuery and it did not work.
$('#lab')
.animate({height: '200px'})
.hide();
If I pass a parameter to hide then it would start working.
$('#lab')
.animate({height: '200px'})
.hide(1);
As it turns out I did not have proper understanding of how effects work in jQuery.
animate method uses a queue inside. This is the queue to which all the pending activities are added.
$('#lab').animate({height: '200px'}).animate({width: '200px'});
In the above code element is being animated twice. However the second animation will not start until the first animation is done. While the first animation is happening the second animation is added to a queue.
Name of this default queue is fx. This is the queue to which jQuery adds all the pending activities while one activity is in progress.
You can inquire an element about how many pending activities are there in the queue.
$('#lab')
.animate({height: '200px'})
.animate({width: '200px'})
.animate({width: '800px'})
.queue(function(){ console.log( $(this).queue('fx').length); $(this).dequeue(); })
.animate({width: '800px'})
.queue(function(){ console.log( $(this).queue('fx').length);$(this).dequeue(); }) ;
In the above code, twice the current queue is being asked to list number of pending activities. First time the number of pending activities is 3 and the second time it is 1.
Method show and hide also accepts duration. If a duration is passed then that operation is added to the queue. If duration is not passed or if the duration is zero then that operation is not added to queue.
$('#lab').hide(); // this action is not added to fx queue
$('#lab').hide(0); // this action is not added to fx queue
$('#lab').hide(1); // this action is added to fx queue
Coming back to the original question
When show or hide method is invoked without any duration then those actions are not added to queue.
$('#lab')
.animate({height: '200px'})
.hide();
In the above code since hide method is not added to queue, both the animate and the hide method are executed simultaneously. Hence the end result is that element is not hidden.
It could be fixed in a number of ways. One way would be to pass a duration to hide method.
$('#lab')
.animate({height: '200px'})
.hide(1);
Another way to fix it would be to pass hiding action as a callback function to animate method.
$('#lab')
.animate({height: '200px'}, function(){
$(this).hide();
});
Another way would be to explicitly put hide method in a queue.
$('#lab')
.animate({height: '200px'})
.queue(function(){
$(this).hide();
})
Since hide method is not added to queue by default, in this case I have explicitly put the hide method to the queue.
Note that inside a queue method you must explicitly call dequeue for the next activity from the queue to be picked up.
$('#lab')
.animate({height: '200px'})
.queue(function(){
$(this).hide().dequeue();
})
.animate({width: '200px'})
In the above code if dequeue is not called then second animation will never take place.
Also note that methods like fadeTo, fadeIn, fadeOut, slideDown, slideUp and animate are ,by default, added to default queue.
Turning off all animations
If for some reason you don’t want animation then just set $.fx.off = true.
$.fx.off = true;
$('#lab')
.animate({height: '200px'}, function(){
$(this).hide();
});
Above code is telling jQuery to turn off all animations and that would result in the element hiding in an instant.