jQuery is a user friendly add-on library for Java Script. They are basically Java Script codes that are written for users i.e. they are designed and implemented on client side (Users Browser) in client server based application.
What dose jQuery actually do?
Well jQuery is the governing factor for bringing about change in appearance or dynamicity of element of web page. They bring about robustness in text and image elements of a web page especially.
Since jQuery first release in Jan 2006 it has been widely accepted by web developer community and has been received hand on hand across the globe. Some of the big names in the business like Microsoft and Motorola have even planed to integrate jQuery along with there web platform. This weak latest version of jQuery was rolled out.
Latest in jQuery
The latest Version 1.5 is a power pack which is here to stay for long. It has covered up may loop holes and bugs that were there in its previous ancestors.
Some of the key factors that are included in jQuery 1.5 :
Ajax Rewrite
AJAX stands for Asynchronous Java Script and XML. jQuery actually makes AJAX simple for end user. What actually AJAX do? Well it helps the user retrieve and send information through web without actually leaving the page. Well jQuery takes all the hectic work away from AJAX it actually makes AJAX communication easy. Instead AJAX functioning you can make jQuery to produce some dynamic effects. But now there has been large number of integration support for AJAX with in jQuery it self.
Deferred Objects
They are logical implementation parts in jQuery. Deferred are introduced in version 1.5, it is a long chain utility of objects like hydro carbon chain that can register multiple callbacks into callback queues, invoke callback queues, and relay the success or failure state of any synchronous or asynchronous function.
Some of the handy codes for deferreds are now built-into $.ajax() no no need to create fuss as for now you’ll get them automatically. Handlers can now be bound like this:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
// $.get, an ajax request, is asynchronous by default. var req = $.get('foo.htm') .success(function( response ){ // do something with the response }) .error(function(){ // do something if the request failed }); // this might execute before the $.get() above is complete doSomethingAwesome(); // something additional to execute upon success, which might, or might not, // have fired by now. With $.ajax deferreds built-in, it doesn't matter. req.success(function( response ){ // do something more with the response // this will fire when success normally fires, or fire immediately // if prior success callbacks have already fired }); |
The above mentioned codes provides you with no boundaries i.e. limited to one success, error, or complete handler anymore, and instead of simple callback functions, these hooks are now self-managed first-in, first-out callback queues.
Well when we move into the matter a bit deeper we find that we can call a function after several concurrent AJAX requests have completed. This is easily accomplished with $.when(), deferred’s little helper method:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
function doAjax(){ return $.get('foo.htm'); } function doMoreAjax(){ return $.get('bar.htm'); } $.when( doAjax(), doMoreAjax() ) .then(function(){ console.log( 'I fire once BOTH ajax requests have completed!' ); }) .fail(function(){ console.log( 'I fire if one or more requests failed.' ); }); |
View this example on jsFiddle
The reason this works is because all of jQuery’s AJAX methods now return an object containing a “promise”, which is used to track the asynchronous request. The promise is a read-only view into the result of the task. Deferreds look for the presence of a promise() method to determine whether an object is observable or not. The $.when() waits for all its AJAX requests to execute, and once they do, the callbacks attached to the $.when() via .then() and .fail() will fire as appropriate (depending on task’s success or failure state). The callbacks fire in the order they were assigned.
It gets better: all deferred’s methods accept either functions or arrays of functions, so you can build your behaviors and assign them all with one call, or in separate calls, as you please.
$.ajax() returns an object packed with other deferred-related methods. I discussed promise(), but you’ll also find then(), success(), error(), and a host of others. You don’t have access to the complete deferred object, though; only the promise, callback-binding methods, and the isRejected() and isResolved() methods, which can be used to check the state of the deferred.
But why not return the whole object? If this were the case, it would be possible to muck with the works, maybe pragmatically “resolve” the deferred, causing all bound callbacks to fire before the AJAX request had a chance to complete. This potentially breaks the whole paradigm.
Registering Callbacks
In the examples thus far I’ve used the then(), success(), and fail() methods to register callbacks onto the deferred, but there are more methods available to you, especially when working with AJAX deferreds. The method you choose ultimately depends on the resolution state(s) you’d like to bind to.
Available to all deferreds (AJAX, $.when, and those created manually):
.then( doneCallbacks, failedCallbacks ) .done( doneCallbacks )
.fail( failCallbacks )
AJAX deferreds have three additional methods.
Two of which map to one of the above. They are provided as semantic alternatives and match the names of the “old” handlers we’re all used to:
1 2 3 |
// "success" and "error" map to "done" and "fail" respectively. .success( doneCallbacks ) .error( failCallbacks ) |
You can register a complete handler that’ll fire regardless of the success or failure state of the request. Unlike success and error, complete is actually an alias to the done method of a separate deferred. This separate deferred, created internally by $.ajax(), is resolved after an AJAX request completes, regardless of the outcome.
.complete( completeCallbacks )
Therefore, the following three examples are equivalent (success reads better than done in the context of an AJAX request, don’t you think?)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 |
$.get("/foo/").done( fn ); // same as: $.get("/foo/").success( fn ); // same as: $.get("/foo/", fn ); Creating your own Deferred We know that $.ajax and $.when implement the deferred API internally, but you can also create your own implementations: function getData(){ return $.get('/foo/'); } function showDiv(){ var dfd = $.Deferred(); $('#foo').fadeIn( 1000, dfd.resolve ); return dfd.promise(); } $.when( getData(), showDiv() ) .then(function( ajaxResult ){ console.log('The animation AND the AJAX request are both done!'); // 'ajaxResult' is the server's response }); |
Inside showDiv() I’m creating a new deferred object, performing an animation, and returning the promise. The deferred is resolved (think of dequeue() if you’re familiar with jQuery’s queuing methods) after the fadeIn() call completes. Between the time the promise is returned and the deferred is resolved, a then() callback is registered to the successful completion of both asynchronous tasks. Therefore, once both tasks resolve, the callback is fired.
getData() returns an object with a promise method, which allows $.when() to observe its eventual resolution. The manually steps we took to return a promise in showDiv() is handled for us internally by $.ajax() and $.when().
Defer your Deferreds
We could take this one step further by registering individual callbacks to both getData() and showDiv(), as well as registering their individual promises onto one “master” deferred.
If you wanted something to happen on the success of getData() and on the success of showDiv() (independently of the other), as well as on the success of both getData() and showDiv() combined, simply register a callback to their individual deferreds, and tie them together with $.when:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 |
function getData(){ return $.get('/foo/').success(function(){ console.log('Fires after the AJAX request succeeds'); }); } function showDiv(){ var dfd = $.Deferred(); dfd.done(function(){ console.log('Fires after the animation succeeds'); }); $('#foo').fadeIn( 1000, dfd.resolve ); return dfd.promise(); } $.when( getData(), showDiv() ) .then(function( ajaxResult ){ console.log('Fires after BOTH showDiv() AND the AJAX request succeed!'); // 'ajaxResult' is the server’s response }); |
Chaining Hotness
Deferred callbacks can be chained so as long as a promise is returned from the function. Here’s a real world example (via @ajpiano!)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 |
function saveContact( row ){ var form = $.tmpl(templates["contact-form"]), valid = true, messages = [], dfd = $.Deferred(); /* bunch of client-side validation here */ if( !valid ){ dfd.resolve({ success: false, errors: messages }); } else { form.ajaxSubmit({ dataType: "json", success: dfd.resolve, error: dfd.reject }); } return dfd.promise(); }; saveContact( row ) .then(function(response){ if( response.success ){ // saving worked; rejoice } else { // client-side validation failed // output the contents of response.errors } }) .fail(function(err) { // AJAX request failed }); |
The saveContact() function first validates the form and saves the result into the variable valid. If validation fails, the deferred is resolved with an object containing a success boolean and an array of error messages. If the form passes validation, the deferred is resolved, except this time the success handler receives the response from the AJAX request. The fail() handler responds to 404, 500, and other HTTP errors that could prevent the AJAX request from succeeding.
Non-observable Tasks
Deferreds are particularly useful when the logic to execute may or may not be asynchronous, and you want to abstract that condition out of the mainline code. Your task might return a promise, but it might also return a string, object, or some other type.
In this example, the first time a “launch application” link is clicked on, an AJAX request tells the server to record (and return) the current timestamp. The timestamp is stored in the element’s data cache after the AJAX request is complete. The application only cares about the initial first click though, so on subsequent clicks, the timestamp is read out of the data cache instead of making an additional trip to the server.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 |
function startTask( element ){ var timestamp = $.data( element, 'timestamp' ); if( timestamp ){ return timestamp; } else { return $.get('/start-task/').success(function( timestamp ){ $.data( element, 'timestamp', timestamp ); }); } } $('#launchApplication').bind('click', function( event ){ event.preventDefault(); $.when( startTask(this) ).done(function( timestamp ){ $('#status').html( ' You first started this task on: ' + timestamp + ' '); }); loadApplication(); }); |
When $.when() recognizes that its first argument doesn’t have a promise (and therefore is not observable), it creates a new deferred object, resolves it with the data, and returns the promise from the deferred. As such, something arbitrary without an initial promise can be observed.
One small gotcha to be aware of (which will most likely be addressed in the next maintenance release), is that you cannot defer an object that implements it’s own promise method. Deferreds are detected by the presence of a promise method, but jQuery doesn’t check to see if the promise actually returns a usable object. Therefore, this will throw a syntax error:
1 2 3 4 5 6 7 |
var obj = { promise: function(){ // do something } }; $.when( obj ).then( fn ); |
Source /
jQuery.sub()
Well J Querry.sub() was invented to provide users with a way of overriding jQuery methods without completely destroying the original methods secondly to achive a high degeree of encapsulation and polymorphism through basic jQuery plugins..
Note : if you’re looking to use this for plugin development you should first strongly consider using something like the jQuery UI widget factory which manages both state and plugin sub-methods. Some examples of using the jQuery UI widget factory to build a plugin are.
The particular use cases of this method can be best described through some examples.
Examples: Example: Adding a method to a jQuery sub so that it isn’t exposed
externally:
1 2 3 4 5 6 7 8 9 10 11 12 13 |
(function(){ var sub$ = jQuery.sub(); sub$.fn.myCustomMethod = function(){ return 'just for me'; }; sub$(document).ready(function() { sub$('body').myCustomMethod() // 'just for me' }); })(); typeof jQuery('body').myCustomMethod // undefined |
Example: Override some jQuery methods to provide new functionality.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
(function() { var myjQuery = jQuery.sub(); myjQuery.fn.remove = function() { // New functionality: Trigger a remove event this.trigger("remove"); // Be sure to call the original jQuery remove method return jQuery.fn.remove.apply( this, arguments ); }; myjQuery(function($) { $(".menu").click(function() { $(this).find(".submenu").remove(); }); // A new remove event is now triggered from this copy of jQuery $(document).bind("remove", function(e) { $(e.target).parent().hide(); }); }); })(); |
// Regular jQuery doesn’t trigger a remove event when removing an element
// This functionality is only contained within the modified ‘myjQuery’.
Example: Create a plugin that returns plugin-specific methods.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 |
(function() { // Create a new copy of jQuery using sub() var plugin = jQuery.sub(); // Extend that copy with the new plugin methods plugin.fn.extend({ open: function() { return this.show(); }, close: function() { return this.hide(); } }); // Add our plugin to the original jQuery jQuery.fn.myplugin = function() { this.addClass("plugin"); // Make sure our plugin returns our special plugin version of jQuery return plugin( this ); }; })(); $(document).ready(function() { // Call the plugin, open method now exists $('#main').myplugin().open(); // Note: Calling just $("#main").open() won't work as open doesn't exist! }); |
Performance and Bug fixes
It’s a win-win deal for jQuery as it has passed all the tests which were conducted on various browsers that supported jQuery.
The true power of jQuery can be unleashed and can be and be felt by hundreds of plug-ins that utilize it to create magic on web. Version 1.5 has used and expanded them to the fullest