What’s New in jQuery 3

jquery-3-header

It’s been ten years since jQuery started rocking the web and it has stuck around for very good reasons. jQuery offers its users an easy-to-use interface to interact with the DOM, perform Ajax requests, create animations, and much more. In addition, unlike the DOM API, jQuery implements the composite pattern. Because of that, you can call jQuery methods on a jQuery collection regardless of the amount of elements included in it (zero, one, or many).

In a few weeks, jQuery will reach an important milestone with the release of version 3. jQuery 3 fixes a lot of bugs, adds new methods, deprecates and removes some functions, and changes the behavior of a few functions. In this article, I’m going to highlight the most important changes introduced by jQuery 3.

New Features

In the following sections I’ll discuss the most important features added in jQuery 3.

for...of Loop

jQuery 3 will offer the possibility to iterate over the DOM elements of a jQuery collection using the for...of loop. This new iterator is part of the ECMAScript 2015 (a.k.a. ECMAScript 6) specification. It lets you loop over iterable objects (including Array, Map, Set, and so on).

When using this new iterator, the value you receive is not a jQuery collection from which you can access one element at a time but rather a DOM element. This iterator will slightly improve the way you can perform operations over a jQuery collection.

To understand how this iterator works, let’s say that you want to assign an ID to each input element of a page. Before jQuery 3 you would write:

var $inputs = $('input');

for(var i = 0; i < $inputs.length; i++) {
   $inputs[i].id = 'input-' + i;
}

In jQuery 3 you can write:

var $inputs = $('input');
var i = 0; 
 
for(var input of $inputs) {
   input.id = 'input-' + i++;
}

New signature for $.get() and $.post()

jQuery 3 adds a new signature for the $.get() and the $.post() utility functions to align them to $.ajax(). The new signatures added are:

$.get([settings])

$.post([settings])

settings is an object that can possess many properties. It’s the same object that you can provide to $.ajax(). To learn more about it, refer to the description included in the $.ajax() page.

The only difference when passing the object to $.get() and $.post() as opposed to $.ajax() is that the method property is always ignored. The reason is that $.get() and $.post() have a preset HTTP method to perform the Ajax request (GET for $.get() and POST for $.post()). Basically, you can’t try to send a POST request via $.get().

Consider the following code:

$.get({
   url: 'https://www.audero.it',
   method: 'POST' // This property is ignored
});

Despite the method property, this statement won’t send a POST request but a GET request.

Use of requestAnimationFrame() for Animations

All modern browsers, including Internet Explorer 10 and above, support requestAnimationFrame. Behind the scenes, jQuery 3 will use this API when performing animations, with the goal of having smoother and less CPU-intensive animations.

unwrap()

jQuery 3 adds an optional selector parameter to unwrap(). The new signature of this method is:

unwrap([selector])

Thanks to this change, you’ll be able to pass a string containing a selector expression to match within the parent element. If there is a match, the matching child elements are unwrapped; otherwise, the operation isn’t performed.

Features Changed

jQuery 3 also modifies the behavior of some of its features.

:visible and :hidden

The new version of jQuery modifies the meaning of the :visible and :hidden filters. 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 now be selected by the :visible filter.

So, if you have the following mark up in a page:

<div></div>
<br />

And you run the following statement:

console.log($('body :visible').length);

In jQuery 1.x and 2.x you’ll obtain 0 as a result but in jQuery 3 you’ll obtain 2.

data()

Another important change is related to the behavior of the data() method. It has been changed to align the method to the Dataset API specifications. jQuery 3 will transform all the properties’ keys to be camel case. To understand this change, consider the following element:

<div id="container"></div>

If you’re using a version of jQuery prior to 3 and you write:

var $elem = $('#container');

$elem.data({
   'my-property': 'hello'
});

console.log($elem.data());

You’ll obtain the following result on the console:

{my-property: "hello"}

In jQuery 3, you’ll obtain this result instead:

{myProperty: "hello"}

Note how in jQuery 3 the name of the property is in camel-case with no dash while in the previous versions it remained lowercase and retained the dash.

The Deferred Object

jQuery 3 changes the behavior of the Deferred object, a precursor of the Promise object, to improve its compatibility with the Promise/A+ proposal. This object and its history are quite interesting. To know more about it, you can either read the official documentation or read my book jQuery in Action, third edition that covers jQuery 3 as well.

In jQuery 1.x and 2.x, an uncaught exception inside a callback function passed to a Deferred halts the program’s execution. Unlike the native Promise object, the thrown exception bubbles up until it (usually) reaches window.onerror. If you haven’t defined a function for this event (which is uncommon), the exception’s message is displayed and the program’s execution is aborted.

jQuery 3 follows the same pattern followed by the native Promise object. Therefore, a thrown exception is translated into a rejection and the failure callback is executed. Once done, the process continues and the subsequent success callbacks are executed.

To help you understand this difference, let’s see a small example. Consider the following code:

var deferred = $.Deferred();

deferred
  .then(function() {
    throw new Error('An error');
  })
  .then(
    function() {
      console.log('Success 1');
    },
    function() {
      console.log('Failure 1');
    }
  )
  .then(
    function() {
      console.log('Success 2');
    },
    function() {
      console.log('Failure 2');
    }
  );

deferred.resolve();

In jQuery 1 and jQuery 2, just the first function (the one throwing the error) is executed. In addition, since I didn’t define any handler for window.onerror, the console message will output “Uncaught Error: An error” and the program execution will abort.

In jQuery 3, the behavior is completely different. You’ll see “Failure 1” and “Success 2” on the console messages. The exception is managed by the first failure function and, once it has been managed, the following success functions are executed.

SVG Documents

No jQuery versions, including jQuery 3, officially support SVG documents. However, the truth is that many methods will just work and others, such as those to manipulate class names, have been updated in jQuery 3 to do so. Therefore, in this upcoming version of jQuery you’ll be able to employ methods such as addClass() and hasClass() with your SVG documents and expect everything to work properly.

Methods and Properties Deprecated or Removed

In addition to the improvements described so far, jQuery also removes and deprecates a few of its features.

Deprecation of bind(), unbind(), delegate() and undelegate()

The on() method was introduced a while ago to provide a unified interface to replace jQuery’s bind(), delegate(), and live() methods. At the same time, jQuery also introduced the off() method to provide a unified interface to replace unbind(),
undelegated(), and die(). The use of bind(), delegate(), unbind(), and undelegate() has been discouraged since then and no further action was taken.

jQuery 3 deprecates all of these methods with the intention of removing them in a future version (possibly jQuery 4). Stick with on() and off() methods for all your projects, so you don’t have to worry about future releases.

Removal of the load(), unload() and error() Methods

jQuery 3 gets rid of the already deprecated load(), unload(), and error() shortcut
methods. These methods were deprecated a long time ago (since jQuery 1.8) but they were still around. If you’re employing a plugin that relies on one or more of these methods, upgrading to jQuery 3 will break your code. Hence, pay attention during the upgrade.

Removal of context, support and selector

jQuery 3 gets rid of the already deprecated context, support, and selector properties. As I mentioned in the previous section, if you’re still using them in your project or you’re employing a plugin that relies on one or more of them, upgrading to jQuery 3 will break your code.

Bugs fixed

jQuery 3 fixes a few important bugs of previous versions. In the following section, I’m going to cover two that will make a huge difference in the way you work.

No More Rounding for width() and height()

jQuery 3 fixes a bug of width(), height() and all the other related methods. These methods will no longer round to the nearest pixel, which made it hard to position elements in some situations.

To understand the problem, let’s say that you have three elements with a width of a third (i.e. 33.333333%) inside of a container element that has a width of 100px:

<div class="container">
   <div>My name</div>
   <div>is</div>
   <div>Aurelio De Rosa</div>
</div>

Prior to jQuery 3, if you tried to retrieve the width of the children elements as follows…

$('.container div').width();

…you’d obtain the value 33 as the result. The reason is that jQuery would round the value 33.33333. In jQuery 3, this bug has been fixed, so you’ll obtain more accurate results (i.e. a floating number).

wrapAll()

The new version of jQuery fixes a bug in the wrapAll() method that occurred when passing a function to it. Prior to jQuery 3, when passing a function to wrapAll(), it wrapped the elements of the jQuery collection individually. Stated in other words, its behavior was the same as passing a function to wrap().

In addition to fixing this issue, since the function is called only once in jQuery 3, it isn’t passed the index of the element within the jQuery collection. Finally, the function context (this) will refer to the first element in the jQuery collection.

Downloading jQuery 3 beta 1

If this article was of any interest to you, you might want to try the first beta of jQuery 3. You can obtain it by accessing one of the two URLs below.

It’s also available on npm and you can download it by running the command:

npm install jquery@3.0.0-beta1

Conclusion

Many people state that jQuery is dead and it doesn’t have a place in modern web development anymore. However, its development continues and statistics of its adoption (78.5% in the top million) contradict these claims.

In this article, I’ve walked you through the main changes that jQuery 3 will feature. As you might have noticed, this version is unlikely to break any of your existing projects as it doesn’t introduce many breaking changes. Nonetheless, there are some points to keep in mind when upgrading such as the improvement of the Deferred object. As is always the case before update a third-party dependency, a review of the project will help you spot any unexpected behavior or broken functionality.

Related Resources:

Comments

  • Pingback: Dew Drop – March 2, 2016 (#2200) | Morning Dew()

  • A script on your site may be infected with something. Every time I load this page, the file “ect.html.gz” suddenly gets downloaded automatically by chrome.

    Me being on a mac or linux, it is mostly harmless, but if someone were to be on windows and decompress it and load it into IE, it would be VERY bad. According to Malwr, it is a trojan.

    • remotesynth

      I am sorry that is happening to you, though I have checked the site on every machine (PC and Mac) and browser that I have (logged in and incognito) and have not seen this issue. I’ve also not heard anyone else mention it. Are you sure it’s coming from this site?

      • Aurelio De Rosa

        Nothing here as well.

      • airtonix

        I’d double check your third party content providers (adverts, etc)

        • remotesynth

          We don’t have any 3rd party adverts. The only third party providers are Google for surveys and analytics.

        • barbarian

          I’d double check the extension between the keyboard and the chair.

    • CS

      As Joe mentioned, i’m also facing the same issue, telerik portal is flooding my system with “ect.html.gz” file.

      Please look into this.

      • Самуил Петров

        This is caused by some buggy chrome extensions on random pages. Try a “clean” version of the browser and see if the problem persists.

      • barbarian

        It must be the web! They killed Internet for us!

      • remotesynth

        I did research this based upon the earlier comment. It does seem to be linked to a Chrome extension causing Chrome to misinterpret random compressed site assets as a download.

  • Narigo

    The for…of loop does implicitly set a variable called “i”? I hope it doesn’t…?!

    • Aurelio De Rosa

      Hi. It’s a mistake from me in copying the code when I sent the article. It’ll be fixed soon. Thank you for the feedback.

  • Vesselin Vassilev

    The very first code snippet should read:

    $inputs[i].id = ‘input-‘ + i;
    instead of
    $inputs[0].id = ‘input-‘ + i;

  • jQuery is not dead, but looks like it has hit its limit. Not sure what else can be done. It’s already perfect DOM library, however it’s might be needed less these days.

  • Francisco Ramos

    I don’t see much innovation in here really… Does this mean that jQuery is coming to its end?

    • remotesynth

      I think you are confusing a mature product that does it’s job well and mostly requires improvements with a dead/dying product.

      • Francisco Ramos

        I still think jQuery is dead. Haven’t used it in 2 years, and I work on huge projects. Don’t get me wrong, I am a big fan of jQuery. I used it for years, and it was great, but I no longer see the need for it. Do you?

        • I agree that jQuery is needed less and less these days. They could just stop releasing anything at this point because it looks like there is not really what can be do to already great DOM library.

          • Michał Gołębiowski

            People still report issues that get fixed so the fact it works for you doesn’t mean we should stop releasing; others still need updates.

          • Of course, by “They could just stop releasing” meant that at this point jQuery is so mature that even if it stopped development completely – it wouldn’t make much difference.

  • Samarjit

    The camel case data API seems to be hard to navigate, spot with eyes. I find this really irritating even while working with angularjs. Other changes looks fine.

  • Jake

    I believe
    $inputs[0].id = ‘input-‘ + i++;
    in the first example should be
    $inputs[i].id = ‘input-‘ + i++;

  • kerrywebster

    Bravo! Nice Work. Thanks for all the info.

  • the for of loop does not need transpilation?

    • Aurelio De Rosa

      It needs to be transpiled in browsers that don’t support it like old versions of Safari.

  • Juan Carlos Pérez

    I expect in further jQuery releases something for DOM optimization…. Other players use the virtual DOM pattern to avoid performance issues on DOM painting. Otherwise in 5 years the addoption will drop from 78% to less than 50%. I saw jQuery growing since 2006. But I am seeing it falling now as well. Keep the good work jQuery team…. And don’t fall behind!

  • jeffdill2

    It’s so odd that `data()` doesn’t already convert the keys to camelCase when explicitly declaring an object on an element, considering that it *does* already convert to camelCase when using `data()` to access data attributes on an element. I.E. the value of this data attribute – – is accessible via `$(‘#whatever’).data(‘somethingReallyCool’)`.

  • Is there any difference in using the new For..of loop rather than .each()?

  • Can you please clarify what’s new with for...of loop? You can iterate over jQuery collection with for..of since v2.2.0.