jQuery 1.4.3 Released

Posted on by

jQuery 1.4.3 is now out! This is the third minor release on top of jQuery 1.4, fixing some bugs and landing some nice improvements.

I would like to thank the following community members that provided patches and input for this release: Anton M., Justin Meyer, Colin Snover, Ryan Tenney, Louis-Rémi Babé, David Petersen, Rick Waldron, Dave Reed, John-David Dalton, temp01, Heungsub Lee, J. Ryan Stinnett, Robert Katic, Juriy Zaytsev, James Burke, Jeffery To, Carl Fürstenberg, Jacob Wright, Jeff Robinson, Christian C. Salvadó, Andrée Hasson, Jason Webster, Dave Furfero, Adam Sontag, Travis Hardiman, DBJDBJ, and Ben Alman.

Along with the following jQuery team members: Scott González, Brandon Aaron, Yehuda Katz, Dave Methvin, Karl Swedberg, Paul Irish, Ralph Whitbeck, Jörn Zaefferer, Richard Worth, Doug Neiner, and Mike Alsup.

Downloading

As usual, we provide two copies of jQuery, one minified (we now use the Google Closure Compiler as the default minifier) and one uncompressed (for debugging or reading).

You can feel free to include the above URLs directly into your site and you will get the full performance benefits of a quickly-loading jQuery.

Additionally you can also load the URLs directly from Google’s CDN:

General Improvements

We’ve made a number of improvements to the internals of jQuery and to the guidelines that we use for development.

JSLint

To start jQuery is now passing Douglas Crockford’s JSLint tool. We’ve integrated his tool into our workflow (checking out jQuery from Github and running ‘make lint’ will show the results) – giving us the ability to keep on top of possible regressions.

We’ve made a few minor changes to JSLint to suit our particular development style and have documented the results in the jQuery Core Style Guidelines.

Modularity

We’ve also removed a number of the inter-dependencies that exist in the jQuery source (inbetween modules). Doing this allows for a greater amount of flexibility when using a copy of jQuery from source. For example you could now use a script loader, such as LABjs or RequireJS to dynamically load individual jQuery modules (e.g. core, support, data, and events).

Additionally this change has made it so that you no longer need to build a copy of jQuery in order to run the jQuery test suite. This has dramatically improved our development workflow – allowing us to quickly make changes to jQuery and test the results without a (comparatively) slow build step.

New Features

All new features and changes can be found in the jQuery API documentation for 1.4.3.

CSS Module Rewrite

Nearly the entire CSS module has been rewritten focusing entirely on extensibility. You can now write custom CSS plugins that extend the functionality provided by .css() and .animate().

For example here is a plugin written by Louis-Rémi Babé that takes advantage of the new functionality: jQuery Rotate.

The plugin provides a cross-browser means of setting and animating the rotation of DOM elements just by using the traditional jQuery methods, like so:

$('#myDiv').css('rotate', 90);
$('#myDiv').animate({rotate: 180});

During the rewrite we broke down the functionality contained within jQuery into two very clear paths: Getting and setting an element’s .style property (done through jQuery.style) and getting the current computed style information of an element (done through .css() and jQuery.css – note that jQuery.curCSS is no longer used and is deprecated as a result). The functionality provided by .css() uses both the jQuery.style and jQuery.css methods.

Making this change has allowed for some speed-ups in computed style retreival, as well – yielding results that are up to 20% faster.

jQuery 1.4.3 .css() Getting a Value

The raw data for all the performance tests can be found in the following Google Doc Spreadsheet. All tests can be found in the jQuery source repository.

Data

The data module has seen a number of improvements greatly increasing its utility.

HTML 5 data- Atributes

To start the primary functionality provided by the jQuery Metadata plugin has been moved into core. HTML 5 data- attributes will be automatically pulled in to jQuery’s data object.

For example, given the following HTML:

<div data-role="page" data-hidden="true" data-options='{"name":"John"}'></div>

All of the following jQuery code will work.

$("div").data("role") === "page";
$("div").data("hidden") === true;
$("div").data("options").name === "John";

Note that strings are left intact while JavaScript values are converted to their associated value (this includes booleans, numbers, objects, arrays, and null).

The data- attributes are pulled in the first time the data property is accessed and then are no longer accessed or mutated (all data values are then stored internally in jQuery).

JavaScript Objects

A number of changes were made to when .data() is used on JavaScript objects (or, more accurately, anything that isn’t a DOM node). To start whenever you set data on a JavaScript object the data is set directly on the object – instead of going into the internal data object store. Additionally events that are attached to objects are put in a new ‘__events__’ property that is actually a function. This was done to allow events to be attached directly to an object, be garbage collected when the object is collected, and not be serialized by a JSON serializer. These changes should make jQuery’s data and event systems much more useful on JavaScript objects.

Events

jQuery has already had setData and getData events (which are broadcast whenever data is set or gotten through the .data() method) – overriding these methods makes it possible to override the default behavior for those features (namely you can return a different value or prevent a value from being set. Note that in jQuery 1.4.3 these events no longer bubble (allowing them to bubble proved to be too costly in most applications).

In 1.4.3 we’ve introduced a new event called changeData. This event is fired after any individual data properties are changed when using .data(). For example:

var user = new User();
$(user).bind("changeData", function( event, name, value ) {
  $("#user").find("#" + name).val( value );
});

The changeData event is used extensively by the new jQuery Data Linking plugin. It makes it possible for the data API to synchronize setting of JavaScript object properties with form fields.

Misc

There was one minor API change to .data() in 1.4.3: Calling .data(Object) no longer completely replaces the data object instead it extends the existing object, leaving the unspecified values in place. We found this to be the expected result based upon a number of confused bug reports.

Traversing

The performance of nearly all the major traversal methods has been drastically improved. .closest(), .filter() (and as a result, .is()), and .find() have all been greatly improved.

These improvements were largely the result of making greater use of the browsers querySelectorAll and matchesSelector methods (should they exist). The jQuery project petitioned the browsers to add the new matchesSelector method (writing up a test suite, talking with vendors, and filing bugs) and the whole community gets to reap the excellent performance benefits now.

jQuery 1.4.3 .closest() Performance

jQuery 1.4.3 .filter() on a Single Element

jQuery 1.4.3 .find() on an element

The raw data for all the performance tests can be found in the following Google Doc Spreadsheet. All tests can be found in the jQuery source repository.

The above performance results specifically look at three very common cases in jQuery code: Using .closest() on a single DOM node, using .filter() (or .is()) on a single DOM node, and using .find() rooted on a DOM element (e.g. $(“#test”).find(“something”)).

Note that the the browsers shown are those that actually support querySelectorAll or matchesSelector – existing browsers that don’t support those methods continue to have the same performance characteristics.

Ajax

A few new Ajax features have landed which should help plugin authors and those building progressively-enhanceable applications.

A new jQuery.readyWait property has been introduced which, when added to, delays the execution of the ready event. This should be used by plugins that wish to delay the ready event from occurring until a specified time. For example RequireJS has already implemented the use of this property allowing you to load dependencies that should be handled before the ready event fires. Whenever an item finishes loading you should end up calling jQuery.ready(true) (and if all dependencies are finished loading – and the DOM is ready – then the ready event will fire).

We’ve also added a new support property: jQuery.support.ajax. Simply this returns true in browsers that are capable of handling an ‘Ajax’ (XMLHttpRequest) request.

Events

.bind(“click”, false) and .unbind(“click”, false)

A convenient shortcut for binding a function that does nothing but return false (preventing the default action and stopping the event bubbling).

.click(data, fn)

All built-in event methods (such as .click()) now accept data as an initial argument (much like the bind method does).

event.namespace

A new property of the event object that contains the event namespace that was passed in to .trigger().

Effects

.show(speed, easing, callback), etc.

All animate methods now support easing. Much like how .animate() supports an easing argument (to be utilized by an easing plugin)

jQuery.fx.interval

A new property that exposes the rate at which all effects fire (in milliseconds – defaults to 13). Making this number smaller will make animations smoother in some browsers (such as Chrome) at the expense of CPU.

Misc

jQuery.type

Determine the internal JavaScript [[Class]] of an object. A number of different aspects are utilized to determine the exact return value for an object. The logic can be determined as follows:

  • If the object is undefined or null then “undefined” or “null” is returned accordingly.
  • If the object has an internal [[Class]] equivalent to one of the browser’s built-in objects we return the associated name. (More details about this technique.)
    • jQuery.type(true) === “boolean”
    • jQuery.type(3) === “number”
    • jQuery.type(“test”) === “string”
    • jQuery.type(function(){}) === “function”
    • jQuery.type([]) === “array”
    • jQuery.type(new Date()) === “date”
    • jQuery.type(/test/) === “regexp”
  • Everything else will return “object” as its type.

jQuery.isWindow

A simple method for determining if an object is likely to be a window.

jQuery.isWindow(window); // true

Additionally we now use he native Array.isArray method for jQuery’s isArray (if available) and we utilize the native String trim method provided by the browser (again, if available). A number of performance improvements were made to jQuery.trim, detailed in the following thread.

Testing

jQuery 1.4.3: Passing 3621 Tests in All Browsers

jQuery 1.4.3 is passing 3621 tests on all supported browsers. We’re 100% passing on Firefox 4 and nearly passing in IE 9 (we discovered two bugs, filed them, and one of them has already been fixed).

55 thoughts on “jQuery 1.4.3 Released

  1. Something changed in the .post() with jQuery 1.4.3 and Firefox 3.6.10 doesn’t like it anymore :

    When my page is ready, to post() are fired.
    Now they crash with this cryptic message :

    uncaught exception: [Exception… “Illegal operation on WrappedNative prototype object” nsresult: “0x8057000c (NS_ERROR_XPC_BAD_OP_ON_WN_PROTO)” location: “JS frame :: https://agence.dagence.pro/interface/jquery.js :: anonymous :: line 134″ data: no]

    Chorme says :
    Uncaught Syntax error, unrecognized expression: #.*$/ (line 84)

    i used minified jquery, concatenated with other libs, but never we have seen this bug before

  2. The performance increases to find will be a great performance increase for widget developers where the HTML is name-spaced / self-contained! Huzzah!

  3. Anthony Butcher on said:

    Something in the new release interferes with the jquery ui draggable/droppable that is connected to a sortable in Chrome. When an item is dragged, it selects most of the page as if I was highlighting it with the mouse. Works fine in IE and Firefox though.

    If I switch the script back to 1.4.2 it works as normal in Chrome.

  4. about my bug, tried with the dev version (not the minified).
    Firefox : anonymous :: line 5498″ data: no
    Chrome : line 3231 Uncaught Syntax error, unrecognized expression: #.*$/
    I confirm it worked flawlessly in 1.4.2

  5. I love how jQuery not only gets better with every release, but a lot faster too. Thanks for focusing so much on performance – it rocks! :)

  6. Ricardo on said:

    It bugs me that you can’t get all data attributes by calling data() without parameters.

    <div id=”test” data-test=”hello”></div>
    $(‘#test’).data(‘test2’, “hi”)

    .data(‘test’) => “hello”
    .data()[‘test2’] => “hi”
    .data()[‘test’] => undefined

  7. mike c. on said:

    I have recently found that animations in chrome run in a very “unsmooth” manner compared to FF4, IE9 orOpera (opera works flawlessly with that), I have tried to jQuery.fx.interval = 1; but chrome still renders animation in very bad way, is there any way to get around that?

    very good update, you are very cool, guys!

  8. Hugo Zapata on said:

    Regarding the added property: jQuery.support.ajax
    I don’t understand the purpose if all the browsers supported by jquery already support ajax. Is there a case when jquery is supported but ajax is not?
    Thanks

  9. Ezekiel Victor on said:

    Awesome… Thanks so much! Love how you included custom event data as the first parameter for the shorthand event bind methods.

  10. @mike c.

    try *increasing* the frame rate (thanks so much for the option to do so, btw). Prior to 1.4.3 I used a little custom plugin to hack the interval and make animations smoother.

    Once you start running a few animations in parallel, especially something with alpha channels, the CPU usage goes up a lot, and garbage collections become frequent and noticeable this will cause jolting animation in firefox 3.5 or older, and chrome/safari.

    I generally knock the frame rate up from 13ms to 25-30ms, your eye can’t tell the difference for most things.

  11. jitter on said:

    @Da Scritch

    Can you please provide a condensed testcase and report this at bugs.jquery.com

  12. Stephane on said:

    It’s a great great news, and an amazing work but when i test my website which use a lot JQuery, the DOM changes are slower ! :( don’t know why but i’m dissapointed !

  13. Leo Dillon on said:

    I thought the new .data() functionality would be amazing at first glance… but on second glance I realised that it is entirely broken. Please change the way this works asap before someone gets hurt.. please.. for the children :(

    I posted about it on Reddit here:

    http://www.reddit.com/r/programming/comments/ds42b/jquery_143_released/c12l6z9

    Honestly the way this is implemented makes no sense at all, I don’t know if this was a complete oversight, a rush to release without every feature being checked over, or maybe someone was up too late at night working on this feature, but the way it works is totally insane.

    But great work in general! I’m loving the speed-up, particularly .closest() which I get a lot of use out of. Thanks to everyone involved!

  14. I fully agree with Leo. The data type detection of html5 data- attributes makes them quite literally unusable. I don’t see a way to pass “true” as a string via one of these attributes. If the value of a data- attribute can be a complex type (ie: boolean or object structure), then strings SHOULD be denoted by quotes. data-name='”true”‘ MUST be permitted and detected properly as a string, with the quotes removed.

    Current implementation is simply broken. At the very least, make the fix backwards compatible – if quotes are detected around the value, parse it as proper JSON by removing the surrounding quotes. If need be, an unquoted value that is not true/false/null can fall back to being a string rather than a parse error.

    Seriously, please fix this. Cannot be currently used in any project where the value of a data- attribute is a dynamic string that could be equal to “true”, “false” or “null”.

  15. Very nice, I like the .filter() and .find() improvements. Not completely sure what “The jQuery project petitioned the browsers to add the new matchesSelector method” means but if you guys managed to communicate with all those people, and succeeded… well… I find that really impressive.

    Very excited about the .data() and I don’t mind the automatic datatype detection at all (though I’ve only just upgraded and haven’t tested everything). The way I see it, you can always call .toString().

    Actually, that might be a way to fix this problem. If you were to overwrite .toString() of the output of the .data() to return the original string.

    thinking out loud:
    var x=$(“#logo”).data(“blah”); //contained [1, 2, 3]
    x.toString=function(){ return this.originalString; }; //would have returned “1,2,3”; should now return “[1, 2, 3]”
    var result=x.toString();

    only combine this into .data() so that:
    var result=$(“#logo”).data(“blah”).toString();

  16. Leo Dillon on said:

    Dima: Wouldn’t this break the expected functionality if you *actually* wanted to use .toString() on one of these returned values? Besides, it’s a really unnecessary workaround when everything can just be parsed as JSON with a fallback to string.

    Even if the functionality of this was fixed in a future version of jQuery it likely wouldn’t adversely affect anyone currently using the function *except* for the people who have decided that it’s broken and need to pass strings with double-quotes and then check the the return from .data() to see if it’s a string and parse as JSON themselves (which is the only current solution, but one which I am not ready to implement as it is a ridiculous and unnecessary workaround and I would rather see this fixed!)

    Consider: Anyone who uses it for strings now will (hopefully) be aware that their string cannot contain any of: null, true, false, [], {}, etc. and therefore will need to have a very strict set of conditions that they are adhering to for strings… the chance of someone’s string accidentally containing double quotes and being a valid JSON string when they are taking pains to ensure that their string doesn’t contain any *other* valid JSON is extremely small – in fact anyone to whom this applies most likely has broken code anyway.

    When I use:

    $(“div”).data(“variable”)

    The result from .data() should simply be equivalent to this:

    try{
    var variable = jQuery.parseJSON( $(“div”).attr(“data-variable”) );
    }catch(e){
    var variable = $(“div”).attr(“data-variable”)
    }

  17. is there a specific reason why the `setData`, `getData` and `changeData` events aren’t publicly documented?

    Same for the `.data(object)` assignment syntax?

  18. Congratulations on the release! I’m impressed by all performance improvements!
    I also really like the support for data attributes, it’s something I use a lot.

  19. Bill Hubbard on said:

    When will jQuery UI be updated to support this? I dropped jQuery 1.4.3 into my application and a bunch of stuff quit working. I keep hitting a “handler is not defined” error in jQuery.event.add, which is getting called from a bind in _mouseInit in jQuery UI mouse, which came down through $.widget > $.Widget.prototype._createWidget > UI draggable _create.

  20. Franky on said:

    Great job!
    Nice lib, docs, examples, etc…

    Do you plan to “upgrade” the .live() as you did for the .bind()
    with the last parameter false?

  21. Luis Miguel on said:

    Thanks for the hard work, guys.

    I was going to try 1.4.3 because I use .find to traverse very big DOMs. I was expecting huge speed ups, as reported by users, but I just found that my application just runs _a lot_ slower.

    With 1.4.2 I was able to traverse my entire DOM a few times to make some .hide() and .show(), but now with 1.4.3 it lasts forever. I’m using IE7 and now it gives four times the message “A script is going too slow. Do you want to cancel it?”. Then it finish its work.

    Could it be that trying to improve the performance for modern browsers, you make slower the older ones?

    Thank you!

  22. Clothere G on said:

    Is there a intellisense module for VS packaged with this new version? Or is it only for version 1.4.1?

  23. Sergey on said:

    var winObj = $(‘Left AND Top set no Zero’)
    .hide()
    .appendTo(‘body’)
    .css({
    width : 100,
    height : 100,
    left : ‘100px’,
    top : ‘100px’,
    position : ‘absolute’,
    opacity : 0
    }).animate({
    width : 420,
    height : 150,
    opacity : 1,
    left : ($(window).width() / 2 – 210) + ‘px’,
    top : Math.round($(window).height() / 5) + ‘px’
    }, 450, function() {
    console.log(‘animation complete’);
    console.log(winObj.attr(‘style’));
    console.log(winObj.css(‘left’));
    console.log(winObj.css(‘top’));
    });
    console.log(winObj.attr(‘style’));
    console.log(winObj.css(‘left’));
    console.log(winObj.css(‘top’));

    Result in:
    display: none; width: 100px; height: 100px; left: 0px; top: 0px; position: absolute; opacity: 0; overflow: hidden;
    0px
    0px
    animation complete
    display: none; width: 420px; height: 150px; left: 741.5px; top: 117px; position: absolute; opacity: 1;
    0px
    0px

    JQuery 1.43Pre show it correctly.

  24. artnik on said:

    The css(‘rotate’, 90); doesn’t work in Opera 1.10. I have no test it in Opera 10.6 yet