Diya Tech Lab Blog

22
Feb - 2018

jQuery 3 – New Cool Features and Major Improvements in Performance

diyatechlab
Diya Tech Lab - jQuery 3

jQuery, the world’s most popular JavaScript library, has been a boon for a lot of us web developers all over the world. From the time of its first release in 2006 till today, many of us web developers have used this amazing library in our projects to make our life easier.

jQuery is mostly used cross-platform JavaScript libraries. jQuery is engineered to be extensible and lets us build our own jQuery plugins very easily. It’s main goal is to give developers a simpler, faster and cross-browser substrate for DOM manipulation.

 

jQuery has three main versions:

 

  •  1.x: currently at v. 1.12.4 and is the first generation jQuery library. It is to be used if you support Internet Explorer 6-8
  • 2.x: currently at v. 2.2.4, the second generation drops Internet Explorer 6-8 support, it’s slimmer compared to its predecessor, and it offers the same API’s.
  • 3.x: currently at v. 3.1.1, and the latest version of the library covered in this article. jQuery 3 was released in June 2016.

 

As of today, we can say that the jQuery foundation implements only jQuery 3.0. The previous versions are supported only for critical patches.

If you want to download jQuery 3.0 to try for yourself, go right to the download page. It’s also good to havea look at the Upgrade Guide, or the source code.

If you want to see or test how your existing project works with jQuery 3.0, you can give a try to the jQuery Migrate plugin that identifies compatibility issues in your code. You can also check into future milestones.

 

Major Changes and new features in jQuery 3

 

» Old IE Workarounds Got Removed

One of the main goals of the new release was to make it faster and sleeker, therefore the old hacks and workarounds related to IE9- got removed. This means if you want or need to support IE6-8, you’ll have to keep using the latest 1.1 release, as even the 2.x series doesn’t have full support for older Internet Explorers (IE9-). Check out the notes on browser support in the docs.

 

jQuery Browser Support

 

» jQuery 3.0 Runs in Strict Mode

As most browsers supported by jQuery 3 support strict mode, the new major release have been built with this directive in mind.

Although jQuery 3 has been written in strict mode, it’s important to know thatyour code is not required to run in strict mode, so you don’t need to rewriteyour existing jQuery code if you want to migrate to jQuery 3. Strict & non-strict mode JavaScript can happily coexist.

There’s one exception: some versions of ASP.NET that – because of the strict mode – are not compatible with jQuery 3. If you’re involved with ASP.NET, you can have a look at the details here in the docs.

 

» For…of Loops is Introduced

jQuery 3 supports the for…of statement, a new kind of for  loop, introduced inECMAScript 6. It gives a more straightforward way to loop over iterable objects, such as Arrays, Maps, and Sets.

In jQuery, the for…of  loop can replace the former $each(…) syntax, and can make it easier to loop through the elements of a jQuery collection.

 

1
2
3
4
5
6
7
8
9
var elems = $(".someclass");
// Classic jQuery way
$.each(function(i, elem){
//work with elem (or "this" object)
});
//Prettier ES2015 way
for(let elem of elems){
//work with elem
}

 

Note that the for…of  loop will only work either in an environment that supports ECMAScript 6, or if you use a JavaScript compiler such as Babel.

 

» jQuery deferred

jQuery.Deferred objects have been updated for compatibility with Promises/A+ and ES2015 Promises.

Promises/A+ is an open standard for interoperable JavaScript promises. A full list of details and requirements can be found here https://github.com/promises-aplus/promises-spec.

For this adoption, the .then() method needs some major changes:

  • An exception thrown in a .then() callback now is a rejection value. In previous jQuery versions, exceptions bubbled all the way up, aborting callback execution, and irreversibly locking both the parent and child Deferred objects.
  • The resolution state of a Deferred created by .then() is now controlled by its callbacks; exceptions become rejection values and return values of functions that are not a then become fulfillment values. In previous jQuery versions, returns from rejection handlers became rejection values.
  • Callbacks are always invoked asynchronously. In previous jQuery versions, they would be called immediately upon binding or resolution, whichever came last, with all the related pain.

 

Look at The Following Code:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
var parent = jQuery.Deferred();
var child = parent.then( null, function() {
return "child";
});
var callback = function( state ) {
return function( value ) {
console.log( state, value );
throw new Error( "grandchild" );
};
};
var grandchildren = [
child.then( callback( "fulfilled" ), callback( "rejected" ) ),
child.then( callback( "fulfilled" ), callback( "rejected" ) )
];
parent.reject( "foo" );
console.log( "parent resolved" );

Run this code in a browser and check the console. In jQuery 3, this will log “parent resolved” before invoking any callback, each child callback will then log “fulfilled child”, and the grandchildren will be rejected with Error “grandchild”.In previous jQuery versions, this would log “rejected child” (the child Deferred having been rejected instead of fulfilled) once and then immediately terminate with uncaught Error “grandchild” (“parent resolved” not being logged and the grandchildren remaining unresolved).jQuery.when has been updated too in order to accept any object that can be used in thencallback, which includes native Promise objects.If for some reason you can’t accept or change your code to follow this new, and a more precise way to handle promises, you can restore the previous behavior by replacing any use of .then() with the deprecated .pipe() method (which has an identical signature).

Added catch() to deferred
The catch() method was added to promise objects as an alias for .then(null, fn).

 

Other improvement in jQuery 3

 

» Error cases exception

Previous jQuery versions always return “something” instead of throwing errors. This can be frustrating because an obvious logical error returns an empty result, which is difficult to handle appropriately.

jQuery 3 in similar scenarios now throws an exception, which can be handled accordingly.

 

» Animation now use requestAnimationFrame

jQuery 3.0, if the browser supports it, uses requestAnimationFrame API to perform animations. The API uses GPU to perform animations. This method is powerful because it’s faster and smoother while performing animations, and on mobile devices, it’s a battery saver.

It is not the first time that jQuery developers have tried to use requestAnimationFrame for animations, but in order to apply it correctly, some code assumptions need to be refactored. The main problem is that requestAnimationFrame is not performed when the browser tab is not active, so jQuery must handle the animation stack correctly.

 

» jQuery custom selectors speedup

jQuery offers some custom selectors (like :visible and :hidden) that apparently look like a CSS selector, but are resolved by jQuery selector engine.

The developers found that with these selectors, some extra work can be skipped if used multiple times in the same document. After they optimized it in jQuery 3, the result is now ~17 times faster.

:visible and :hidden custom selectors can still be expensive because they are based on how each browser implements the DOM flow rendering. This means that sometimes these selectors ask a complete flow recalculation of the whole page, so they must be used with responsibility.

jQuery 3.0 changes the meaning of :visible (and therefore of :hidden) selectors. Starting with jQuery 3.0, elements will be considered :visible if they have any layout boxes, including those of zero width and/or height. For example, br elements and inline elements with no content will be selected by the :visible selector.

unwrap() method

Until jQuery 3.0, the unwrap method did not take any argument.

The .unwrap() method removes the element’s parent. This is effectively the inverse of the .wrap() method. The matched elements (and their siblings, if any) replace their parents within the DOM structure.

Use This Simple HTML Code:

1
2
<div class="row"><span class="detail">row1</span></div>
<div><span class="detail">row2</span></div>

Calling the unwrap method on elements with detail class:

1
$('.detail').unwrap();

..will result at unwrapping all of them, but what if you need to unwrap only elements with a parent with row class? You need to change the selector in order to match its direct parent so do the following:

1
$('.row&gt;.detail').unwrap();

With jQuery 3.0 a selector can be passed to the method in order to check the parent element. If an element parent does not match the selector, the element will not be unwrapped.

This is how it is done in jQuery 3:

1
$('.detail').unwrap('.row');

 

» jQuery and Strict Mode

Today almost all modern browsers support strict mode. jQuery 3.0 has been developed with this in mind.

From MDN (https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Strict_mode):

Strict mode makes several changes to normal JavaScript semantics. First, strict mode eliminates some JavaScript silent errors by changing them to throw errors. Second, strict mode fixes mistakes that make it difficult for JavaScript engines to perform optimizations: strict mode code can sometimes be made to run faster than identical code that’s not strict mode. Third, strict mode prohibits some syntax likely to be defined in future versions of ECMAScript.

This does not imply that you have to rewrite your existing jQuery code. Although jQuery 3.0 has been written in strict mode, it’s not mandatory to have all your code strict mode compliant.

jQuery 3 opens the door to new features and performance advantages.

jQuery 3.0 supports the for…of statement. This iterator is part of ECMAScript 6. It gives a more readable way to loop over iterable objects, such as Arrays, Maps, and Sets. In jQuery 3.0, the for…of loop can be used to replace the $.each(…) usage.

Starting from this simple HTML code:

1
2
<div class="row"><span class="detail">row1</span></div>
<div class="row"><span class="detail">row2</span></div>

..to loop over each element of class row, we usually use:

1
2
3
4
var myRows = $('.row');
$.each(myRows, function(index, value) {
// my code
});

With jQuery 3.0 we can use ES6 for…of, so the same loop will be:

1
2
3
4
var myRows = $('.row');
for(let row of rows) {
// my code
};

Important note: The for…of loop will only work with browsers that supports ECMAScript 6.

 

» get() and post() signature changes

jQuery get() and post() are shorthand for the ajax() function used often to simplify an Ajax call. In jQuery 1.0, the ajax() function can receive a set of key/value pairs that configure the Ajax request. This was not possible with get() and post().

jQuery 3.0 adds this signature for the $.get( ) and the $.post( ) in order to align them to $.ajax( ). Obviously the type option will be ignored and set accordingly from the shorthand function.

 

» escapeSelector

jQuery 3.0 give us the new $.escapeSelector(). The method allows to escape characters that have a different usage as CSS selector, and result in a wrong selection.

Starting from this simple HTML code:

1
<div id="my:terrible.id"></div>

Calling the selector given below, the element is not selected, because special characters must be escaped:

1
$('#my:terrible.id');

With jQuery 3.0 it can be selected like this

1
$('#'+$.escapeSelector('my:terrible.id'));

This method is particularly useful when a class name or an ID contains characters that have a special meaning in CSS, such as the dot or semicolon. Such characters usually occur in legacy applications or auto-generated code. Now instead of using escaping functions, we have the jQuery official one.

 

» XSS attack protection

jQuery 3.0 added an extra security layer for protection against Cross-Site Scripting (XSS) attacks.

From MDN (https://developer.mozilla.org/it/docs/Glossary/Cross-site_scripting):

Cross-site scripting (XSS) is a security exploit which allows an attacker to inject into a website malicious client-side code. This code is executed by the victims and lets the attackers bypass access controls and impersonate users. According to the Open Web Application Security Project, XSS was the third most common Web app vulnerability in 2013.

This new layer requires the developers to specify dataType: ‘script’ in the options of $.ajax() and $.get() methods. Now when you make a request for a script on a domain different from yours, you must now explicitly declare this in the options.

 

» Very minimal SVG support

jQuery has never fully supported SVG and probably this will never change. With jQuery 3.0 methods for CSS class manipulation, .addClass(), .removeClass() and .hasClass() can now be used to manipulate SVG.

Prior to jQuery 3.0 you had to access class attribute as any other attribute, losing the power of jQuery class manipulation functions.

Now jQuery can be used to find an SVG element and style the classes with CSS.

Starting from this simple HTML code:

1
 

..to add a class named power to the rect element you have to use:

1
var myRect = $('.myRect');

// This is a very simple addClass…

1
myRect.attr('class', 'myRect power');

With jQuery 3.0 we can finally manipulate SVG element class:

1
2
var myRect = $('.myRect');
myRect.addClass('power');

 

» Bind()/delegate() deprecated

With jQuery 3 the methods .bind(), .unbind(), .delegate() and .undelegate() are deprecated and they might be removed in future releases.As said previously, the correct method to register an event handler is jQuery is on and the opposite off.

 

» Decimal values by width and height

Before jQuery 3, the jQuery library returned rounded int values with width(), height() and related methods. jQuery 3 now return a floating number; this is particularly relevant when you have to work with exact values on layout and DOM manipulation.

Starting from this simple HTML code:

1
<div id="row" style="width: 12.7px;"></div>

..calling the following code, the result will be My width is: 13:

1
2
var myWidth=$('#row').width();
alert('My width is '+myWidth);

With jQuery 3 the width is returned considering the decimal part, so the result will be My width is: 12.7

 

» Removed deprecated event register

Finally the deprecated load, unload and error, deprecated since jQuery 1.8; are now removed. Remember that the correct method to register an event handler in jQuery is on, and the opposite off.

 

Conclusions

jQuery 3 brings in a lot of new features to the library. All the code needed to support legacy browsers is finally removed, and the code is reengineered to use and support modern features.