New features in jQuery 3
III
Using the JavaScript library jQuery [1], developers can access elements of a web page, manipulate them, handle events conveniently, and communicate with the server via Ajax with very little effort. In this way, jQuery helps build complex, dynamic web applications. Its wide distribution also helps promote large content management systems (CMSs) like Joomla or WordPress, which provide or even use jQuery themselves. A W3Techs [2] statistic even suggests that jQuery is used on two-thirds of all websites worldwide.
Dismantling
On June 9, 2016, the developers released jQuery version 3.0 [3]; an update followed as early as the beginning of July in the form of version 3.1 [4]. Unlike jQuery 2, the newer version does not include basic modifications to the library. Instead, the new version cuts out a few old habits and changes the behavior of some interfaces. Above all, the developers wanted to make jQuery 3 leaner and faster in response to two commonly cited points of criticism.
First, they have removed a few workarounds for Internet Explorer. Unlike many websites and reports suggest, jQuery 3 officially continues to support Internet Explorer from version 9. Anyone wanting to cut their website on older Microsoft browsers should stick to jQuery 2 or jQuery 1.12 – both version will continue to receive bug fixes.
Up to now it was possible to register event handlers using the methods .load()
, .unload()
, and .error()
. However, these methods have been regarded as deprecated since jQuery 1.8 and are gone for good in jQuery 3. Anyone who wants to register event handlers should now use .on()
.
The offset()
function determines the location of an item on the website. It might work, but it doesn't make much sense for offsetting a window, for which the answer is then something like { top: 0, left: 0 }
. In some other situations, jQuery doesn't return meaningful values. In such cases, jQuery 3 throws an exception and no longer silently ignores such "crazy requests" from the programmer.
Gas Pedal
Animations now use the requestAnimationFrame
interface provided by the browser, which means not only do they run more smoothly, they are less of a burden to the processor. All current browsers include the requestAnimationFrame
API with the exception of Internet Explorer up to version 9 and Android before version 4.4. The jQuery developers have been experimenting with the interface for several years, but keep stumbling on various compatibility issues. They might think they have largely remedied the issues, but the program code might still get out of step if it is dependent on near real-time animations.
jQuery makes work easier with just a few unique (CSS) selectors. For example, $(":visible")
supplies all elements that are currently visible on a page. However, evaluating these special selectors takes longer than with native CSS selectors. For example, to determine all visible elements, the worst case scenario is that the browser will need to completely re-render the page. Thanks to Google developer Paul Irish, jQuery now works noticeably faster if such selectors occur frequently in a document.
In the case of :visible
, the developers state that jQuery 3 increases speed by a factor of 17. They also warn that, as before, using the special selectors takes up quite a bit of time. Programmers are therefore better off selecting some items with normal CSS selectors and then only applying them to :visible
, :hidden
, and similar selectors.
New Delays
The greatest changes are with the Deferred objects. They help manage, monitor, and execute multiple asynchronous tasks and, above all, make it easier to communicate with servers via Ajax. In jQuery 3, the jQuery.Deferred
objects are compatible with the Promises/A+ specification or the Promises from ECMAScript 2015. The Deferred interface also passes the tests of the Promises/A+ Compliance Test Suite [5].
Under the hood, the Deferred objects behave differently in several situations: If an exception occurs in jQuery 2, it migrates upward until it eventually reaches window.onerror
, thus usually stopping the program. jQuery 3 converts the exception into a rejection for such cases and then calls a stored callback function.
Listing 1 illustrates this with a simple example: It creates a Deferred
object and then registers a few callback functions using .then()
. The code executes the function submitted in the first parameter of .then()
if a Deferred object assumes the Resolved status and everything has therefore run smoothly. However, the function submitted in the second parameter of .then()
takes effect if the Deferred object assumes the Rejected status.
Listing 1
Deferred Objects in jQuery 3
01 var deferred = $.Deferred(); 02 03 deferred.then(function() { 04 console.log("first callback function"); 05 throw new Error("error occured"); 06 }) 07 .then( 08 function() {console.log( "second callback function"); }, 09 function(e) {console.log(e.message);} 10 ); 11 12 deferred.resolve();
If Listing 1 has registered the callback functions, it immediately changes the deferred
object to the Resolved status. The callback function thus takes on the work in the first .then()
and throws an error immediately. This would have been the end of it in jQuery 2: Only the output first callback function
would have appeared on the console. jQuery 3, on the other hand, converts the exception into a rejection, and the program can run again. Because a rejection is present, jQuery calls the callback function stored as the second parameter with the second .then()
and assigns the error that was previously thrown to the function. In jQuery 3, the messages shown in Figure 1 appear on the console.
Another new feature is shown in Listing 2: With immediate effect, callback functions define the status of the Deferred object themselves. A return value that does not have a .then()
function causes the execution. In jQuery 2, Listing 2 delivers the output Unsuccessful run
, whereas in jQuery 3 it is Successful run
.
Listing 2
Deferred States Demo
01 var deferred = $.Deferred(); 02 03 deferred.then( 04 null, 05 function() { return "run"; } 06 ) 07 .then( 08 function(value) { console.log( "Successful", value); }, 09 function(value) { console.log( "Unsuccessful", value); }, 10 ); 11 12 deferred.reject();
Callbacks now continuously run asynchronously, even if there is a Deferred object is the Resolved status. Figure 2 illustrates this: In jQuery 2, it first outputs Hello World!
and then End of program
, because these callbacks run synchronously, depending on their binding. It is the opposite in jQuery 3, which executes the callback function asynchronously.
The .then()
function behaves differently in several situations in jQuery 3, as well. If you need the old behavior, you need to replace the .then()
in your code with the .pipe()
method to get the old behavior and the same signature as the .then()
method. Promise objects also offer the new .catch()
method, which only works as an alias for the .then(zero function)
.
A new plugin helps when debugging Deferred objects: the jQuery Deferred Reporter [6] provides information on the console that the developers can use to trace the source of their errors.
Buy this article as PDF
(incl. VAT)