The jQuery Project is very excited to announce the dates for our first-ever San Francisco Bay Area conference. The conference will be held at the Microsoft Silicon Valley Research Center in Mountain View, California on April 24th and 25th, 2010.
The San Francisco Bay Area conference is the second of four events planned by the jQuery Project in 2010. The first was the jQuery14 event, and additional conferences are being planned in Europe and on the East Coast for later this year.
This venue is the largest that the project has worked with to date (Harvard Law School in ‘07, the MIT Stata Center in ‘08 and Microsoft New England Research Center in ’09) and we expect to sell out very quickly.
Registration is currently scheduled to open on Wednesday, March 17th; tickets will be priced at $199. In addition to General Admission tickets, we’re offering a limited number of discounted student tickets priced at $99, with a valid student ID.
A brief synopsis of some of the content that you’ll be able to expect:
jQuery
jQuery UI
jQuery Plugins
Complex Application Development
jQuery Case Studies
In addition to two days of jQuery sessions, for the first time we’ll be adding an additional day of jQuery training, prior to the main event. The training will be provided by appendTo and focused on helping you and your team get up to speed on jQuery prior to attending the conference. The training will cover the following topics:
Introduction to jQuery
Finding Something
Doing Something With It
Chaining
Introduction to jQuery UI
Implementing jQuery UI Widgets
The training will be held on April 23rd at the Microsoft San Francisco offices in downtown San Francisco; tickets will cost $299. All proceeds from training go to the jQuery Project.
jQuery 1.4.2 is now out! This is the second minor release on top of jQuery 1.4, fixing some outstanding bugs from the 1.4 release and landing some nice improvements.
I would like to thank the following people that provided patches for this release: Ben Alman, Justin Meyer, Neeraj Singh, and Noah Sloan.
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).
In this release we’ve added two new methods: .delegate() and .undelegate(). These methods serve as complements to the existing .live() and .die() methods in jQuery. They simplify the process of watching for specific events from a certain root within the document.
There has been some large code rewrites within this release, both for performance and for fixing long-standing issues.
Performance Improvements
As is the case with virtually every release of jQuery: We’ve worked hard to continue to improve the performance of the code base, making sure that you’re provided with the best performing JavaScript code possible.
According to the numbers presented by the Taskspeed benchmark we’ve improved the performance of jQuery about 2x compared to jQuery 1.4.1 and about 3x compared to jQuery 1.3.2.
Specifically we’ve improved the performance of 4 areas within jQuery:
While comprehensive benchmarks like Taskspeed can be interesting if deconstructed into individual sub-tests for further study, as a project we tend to stay away from using them as an accurate measure of true, overall, library performance. Considering how many aspects make up a library, not to mention the different techniques that they offer, cumulative results rarely reflect how an actual user may use a library.
For example, we saw significant overall performance speed-ups in Taskspeed simply by optimizing the $("body") selector because it’s called hundreds of times within the tests. Additionally we saw large gains by optimizing .bind() and .unbind() by a fraction of a millisecond – an inconsequential amount – especially considering that any cases where you would bind hundreds of events you would likely want to use .live() or .delegate() instead.
We’ve collected some results from the other major libraries as well but are less interested in those results and far more interested in the performance improvements that we’ve made relative to older versions of jQuery itself.
We will continue to work on optimizing the jQuery code base – indefinitely. It’s always a major concern for us to try and provide the fastest JavaScript/DOM-development experience possible. And yes, there will likely always be ways to gain additional performance – either through internal optimizations or by pushing critical functionality off into browser-land for standardization.
Event Rewrite
The largest internal changes have come through a much-needed structural rewrite of the events module. Many quirky issues related to event binding have been resolved with these fixes.
Namely event handlers are no longer stored as object properties in jQuery’s internal object store (with metadata attached to the handlers). Instead they’re now stored within an internal array of objects.
If you’ve ever had the opportunity to play around with .data("events") on a jQuery element you would find that it returns an object with all the event types currently bound, within it.
To enumerate some of the changes that have occurred during this rewrite:
It’s now possible to bind identical handlers with different data, namespaces, and event types universally.
Execution of event handlers will continue after one handler removes itself (or its sibling handlers).
We no longer attach data/namespace information directly to the event handlers (only a unique tracking ID).
We no longer use proxy functions, internally, to try and encapsulate handlers.
Execution order of events is now guaranteed in all browsers. Google Chrome had a long-standing error in their object-looping logic that has been routed around.
As a side-effect of these changes we had to change the newly-exposed special add/special remove APIs in order to accommodate the new event data objects. Ben Alman is in the process of writing up a large tutorial on jQuery’s special event system and we will be making additional announcements when that occurs.
Bug Fixes
There were a total of 40 tickets closed in this minor release. Some relating to differences between jQuery 1.3.2 and jQuery 1.4.x, some fixing long-standing issues (like in the case of the event module rewrite).
Raw Data
This is the raw data that we collected to generate the aforementioned charts.
Today we’re pleased to announce the brand new jQuery.org web site: The home of the jQuery project.
The jQuery.org site was designed and implemented by jQuery community member Boaz Sender.
You may recognize most of the content from the old jQuery Docs site but it’s been heavily re-organized and presented in a manner more befitting of the larger jQuery project.
This launch goes along with the formalization of the jQuery project, back from when we joined the Software Freedom Conservancy. Having an official home for the larger jQuery project should be good for future growth and organization in the project as a whole. You can learn more about this organization in this video about the jQuery project.
Today we’re officially announcing the brand new jQuery Forum. We’ve been using mailing lists, and subsequently Google Groups, over the past 4 years to manage the discussion and community around jQuery. That particular solution has simply not been able to scale to our discussion requirements both in terms of participation and in managing spam.
When looking for a new area to have discussions, we looked at a wide variety of solutions with a few major requirements: It had to be capable of handling both regular discussions and the now-ubiquitous question & answers that occur. Additionally, we wanted something that lowered the barrier to asking a question — something that anyone would be able to use (thus it had to have a good web interface).
We also wanted a solution that would have a low maintenance threshold for the team. This would mean either using a hosted solution in which the team we were working with was very accommodating or using a solution that we host ourselves that was trivially easy to use and had a good community of developers.
We ended up analyzing countless solutions, but in the end we chose to go with Zoho Discussions (Zoho’s announcement about the move). A combination of decisions drove us to this decision:
Zoho Discussions seamlessly integrates both regular, forum-style, discussions and Q&A. Additionally, all the moderation and administration tools are designed around building and managing a slick workflow for answering questions and concerns.
The Discussions team at Zoho have been incredibly accommodating. They are not only providing all the hosting for free but going out of their way to fix concerns and integrate our full Google Groups back history. We’ve been working very closely with them, and they’ve fixed, or are fixing, every issue that we’ve brought forward.
The jQuery team has transitioned to using the new forum over the past week and have been very pleased with how it’s been working out thus far. Most of the old Google Groups and all of the old jQueryHelp.com posts have been integrated into the new system. We will be doing a final import of the Google Groups posts once we finally close the groups in the next week or two.
We’ve opened up a number of individual forums for discussion.
And finally we’ve opened up a new forum in which you can post questions or concerns that you have with the forum itself: About the jQuery Forum.
As time goes by, we’ll certainly open more as needs arise — especially ones for non-English speaking users.
As it stands the two largest outstanding issues that are being actively worked on are:
There is no way to receive email updates of all posts. You can receive email updates for individual posts that you subscribe to, and you receive email updates for posts that you create, but it’s not possible to subscribe to all of them simultaneously. In the meantime we recommend that you subscribe to the forum RSS feed as a way to see all posts and replies.
Many of the pages on the site are being loaded in an “Ajax” manner which is being replaced with a more traditional (and appropriate) page load. The full transition should be complete very soon.
We’ve collected a number of smaller issues and are communicating actively with the Zoho Discussions team. If you find any more issues please feel free to post them to the About the jQuery Forum forum.
As mentioned before, we analyzed a number of discussion solutions — dozens, in fact. There are a few that we were quite pleased with and were in the final running.
Stack Overflow is pretty much the undisputed king of web-based Q&A. There is already an active community of jQuery users there, as well. We looked at both adopting the existing Stack Overflow community and setting up a Stack Exchange as possible solutions. However, both of those left a major gap: They were not suited to handling regular, non-Q&A, discussions. If we were to use either of those solutions, we would have to set up an additional forum or mailing list just to have plain discussions. In the end we decided to not move ahead with these solutions in favor of something that provided a more-unified community.
We also looked at many traditional forum solutions such as Vanilla Forums. Out of all the ones that we looked at, Vanilla Forums proved to be the best structured towards our needs. With an active and organized plugin community, we were able to find many solutions to our problems. However, in the end there was no good way to provide consistent Q&A using Vanilla, or a set of plugins, exclusively. We would end up having to use it in conjunction with Stack Overflow or another service. Also, we would have to host and develop the solution completely by ourselves, which requires time that we would rather spend in other ways.
We also looked at better mailing list solutions, like Librelist, but they don’t provide any sort of simple web interface (at least not in the way that forum solutions do), making it very difficult for new users to participate and get questions answered. We really have no interest in going back to the old discussion techniques of Google Groups and other mailing list providers.
We want to take this opportunity to thank the Zoho Discussions team for all their hard work in helping us transition over to their software. They’ve been incredibly helpful and we’re very excited to to be working with them.
Additionally we want to thank Chrys Bader, Mike Branski, and the rest of the community at the old jQueryHelp.com forum for being supportive and willing to integrate into the new forum setup.
Thanks again to everyone for their help in this transition. We hope to work out most of the kinks very quickly and are looking to smooth sailing from here on out. Feel free to hop onto the forums and be sure to report any problems that you may have.
We still have 7 more days of jQuery 1.4 to come with more video’s and more releases to announce.
Again, events like these are not possible without support from our great sponsors and from you, the jQuery Community. We’d like to thank everyone who has donated so far, and we’d like to remind everyone that you will receive a free ebook with the donation of $20 or more throughout the 14 Days of jQuery.
Media Template Giveaway
Each day during the 14 days of jQuery, a web developer will receive a free (gs) Grid-Service account for one year from the jQuery Project’s web hosting provider, Media Temple. A grand prize winner will receive a 13″ MacBook Pro!
In order to enter the contest, you must submit a link to your coolest use of jQuery. A winner will be chosen each day during the 14 Days of jQuery. The grand prize winner will be announced on Friday, January 29th.
Check the Media Template Giveaway webpage for more details about the contest and to see the announced daily winners. There are only 7 days left, so enter now!
Check out jQuery Enlightenment!
jQuery team member Cody Lindley has published the jQuery Enlightenment book, and if you haven’t checked it out yet, you’ll definitely want to. “Each chapter contains concepts essential to becoming a seasoned jQuery developer,”‘” so even if you’ve already got your copy, pick one up for a friend who’s just learning! Even better, a percentage of all sales goes directly back to the jQuery project and helps fund future releases and projects. A big thank you to Cody for his generous donation for the 14 Days of jQuery campaign!
In celebration of jQuery’s 4th birthday, the jQuery team is pleased to release the latest major release of the jQuery JavaScript library! A lot of coding, testing, and documenting has gone into this release, and we’re really quite proud of it.
I want to personally thank Brandon Aaron, Ben Alman, Louis-Rémi Babe, Ariel Flesler, Paul Irish, Robert Katić, Yehuda Katz, Dave Methvin, Justin Meyer, Karl Swedberg, and Aaron Quint who put a lot of work into fixing bugs and getting the release out the door.
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).
Additionally, Google has provided us with a copy of jQuery hosted on their servers. This copy of jQuery is automatically minified and gzipped – and served from Google’s fast edge cache servers.
You can feel free to include the above URL directly into your site and you will get the full performance benefits of a quickly-loading jQuery.
With jQuery 1.4 we attempted to minimize any large upgrade hassles – maintaining the signatures of all public functions. That being said, please read through the list of potentially-breaking changes to be aware of what might cause problems in your applications.
Features
Below is an overview of all the changes and functionality added to jQuery 1.4. Additionally all of the changes have been documented in the jQuery 1.4 docs.
Performance Overhaul of Popular Methods
Many of the most popular and commonly used jQuery methods have seen a significant rewrite in jQuery 1.4. When analyzing the code base we found that we were able to make some significant performance gains by comparing jQuery against itself: Seeing how many internal function calls were being made and to work to reduce the complexity of the code base.
// find all ampersands in A's and wrap with a span
$('a').html(function(i,html){
return html.replace(/&/gi,'<span class="amp">&</span>');
});
// Add some information to the title of the anchors
$('a[target]').attr("title", function(i,title){
return title + " (Opens in External Window)";
});
jQuery 1.4 adds support for nested param serialization in jQuery.param, using the approach popularized by PHP, and supported by Ruby on Rails. For instance, {foo: ["bar", "baz"]} will be serialized as “foo[]=bar&foo[]=baz”.
In jQuery 1.3, {foo: ["bar", "baz"]} was serialized as “foo=bar&foo=baz”. However, there was no way to encode a single-element Array using this approach. If you need the old behavior, you can turn it back on by setting the traditional Ajax setting (globally via jQuery.ajaxSettings.traditional or on a case-by-case basis via the traditional flag).
There are three ways to enable the traditional way of serialization:
// Enables for all serialization
jQuery.ajaxSettings.traditional = true;
// Enables for a single serialization
jQuery.param( stuff, true );
// Enables for a single Ajax requeset
$.ajax({ data: stuff, traditional: true });
If the response to an Ajax request is returned with a JSON mime type (application/json), the dataType defaults to “json” (if no dataType is specified). Additionally, if the response to an Ajax request is returned with a JavaScript mime type (text/javascript or application/x-javascript) , the dataType defaults to “script” (if no dataType is specified), causing the script to automatically execute.
By default, jQuery ignores the Last-Modified header for Ajax requests, preferring to make request and ignore the browser cache. Specifying ifModified: true causes jQuery to use the browser cache if available. jQuery 1.4 will also send the If-None-Match header (for ETag support) if you specify ifModified.
jQuery 1.3 and earlier used JavaScript’s eval to evaluate incoming JSON. jQuery 1.4 uses the native JSON parser if available. It also validates incoming JSON for validity, so malformed JSON (for instance {foo: "bar"}) will be rejected by jQuery in jQuery.getJSON and when specifying “json” as the dataType of an Ajax request.
You can now specify a context for an Ajax request, and all callbacks will have that context set (allowing you to simplify your code and possibly avoid having to use closures, or use other objects).
The success callback for any ajax request now receives the XMLHttpRequest object as the third argument. Previously this XHR object was only accessible as the return value for $.ajax and the like.
In jQuery 1.3, the contentType setting was ignored in jQuery.ajax if no data was sent. In jQuery 1.4, the contentType is always sent. This fixes an issue with some backends that used the Content-Type header to decide what kind of response to send.
You can now pass in negative numbers for .get() and .eq(). For example, you can select the second-to-last div or, you can access the DOM element for the same:
.get() has historically returned an Array from the jQuery set. For further clarity, you can use .toArray() to achieve the same thing in jQuery 1.4. Unlike, .get(), however, .toArray() does not take an argument.
In jQuery 1.3, jQuery() returned a jQuery set containing just the document. in jQuery 1.4, it returns an empty jQuery set. This can be useful for creating an empty set and adding elements to it dynamically. Note: The jQuery().ready() technique still works in 1.4 but it has been deprecated. Please use either jQuery(document).ready() or jQuery(function(){}).
All three now use the same code path (using document.createElement), improving performance for jQuery("<div></div>"). Note that if you specify attributes, we use the browser’s native parsing (using innerHTML).
CSS
The performance of the .css() method has seen a 2x performance improvement.
The performance of the .addClass(), .removeClass(), and .hasClass() methods has seen a 3x performance improvement.
It is sometimes desirable to work with the data attached to an element as a complete object. A common example would be wanting to copy the entire data from one element to another. In jQuery 1.4, .data() with no parameter returns the entire object, and .data(Object) sets the object. Keep in mind that this object includes events bound to the element, so use caution.
jQuery uses a unique expando on DOM elements that is used to get the .data() for a particular element. jQuery now avoids creating that expando when data is looked up but no data has been added. This potentially increases performance and avoids polluting the DOM in these cases.
In addition to being able to specify an easing function for an animation you can now specify an easing animation for individual properties. James Padolsey has more information and demos in his blog post.
If you want to ensure that “this” inside a function will be permanently bound to a particular value, you can use jQuery.proxy to return a new function with that scope.
The change and submit events work reliably across browsers for both normal and live events. We override the normal change and submit events in Internet Explorer and replace them with events that work identically to the other browsers.
focusin and focusout are generally equivalent to focus and blur but bubble, which helps tremendously if you are writing your own event delegation behavior. Please note that `focus` and `blur` will not work with the live() method; this was a design decision due to the DOM Events spec defining focus/blur do not bubble.
$("form").focusout(function(event) { var tgt = event.target; if (tgt.nodeName == "INPUT" && !tgt.value) { $(tgt).after("<span>nothing here</span>"); } });
With the exception of ready, focus (use focusin instead), and blur (use focusout instead), all events that can be bound using .bind() can also be live events.
We’re very proud to count some addtional events amongst those supported by live(). 1.4 introduces cross-browser support for change, submit, focusin, focusout, mouseenter, and mouseleave via the event delegation in .live().
Note that if you need a live focus event, you should use focusin and focusout rather than focus and blur, because, as mentioned, focus and blur do not bubble.
Also, live() also now accepts a data object, just as bind() has. (Commit)
You can now specify a context to the selector that will be used to bind a live event. If you do, only elements under that context will be bound. While the elements themselves do not need to exist when you create the live event, the context must exist.
detach() removes an element from the DOM but does not remove the associated event handlers. This is appropriate for temporarily removing an element to manipulate and then return.
var foo = $("#foo").click(function() { // do something }); foo.detach(); // foo retains event handlers foo.appendTo("body");
jQuery caches the resulting nodes created using methods like jQuery("<div>") and .after("<div>"). This results in significantly faster performance on pages that do DOM manipulation with strings using these methods.
before, after, replaceWith on disconnected nodes (commit)
You can now use before, after, and replaceWith on nodes that are not attached to the DOM. This allows you to do more complex manipulations before inserting the final structure into the DOM. This also prevents reflows from occuring while the manipulation is taking place.
In jQuery 1.3, .clone(true) did a deep clone, but did not clone data. In jQuery 1.4, it clones data, which means that events are cloned as well. This uses the same semantics as jQuery.extend, so plain objects and Arrays are cloned, while custom objects are not.
The .delay() method will delay any further elements in the queue for the specified number of milliseconds. By default, it will use the fx queue. You can specify an alternate queue as an optional second parameter to the delay function.
In jQuery 1.4 the function that’s called is passed in another function, as the first argument, that when called automatically dequeues the next item and keeps the queue moving.
Queues can now be cleared. This will remove any unexecuted functions from the queue, but not stop running functions. Using .clearQueue() without any parameters will clear the fx queue.
The new “until” methods function similarly to .nextAll(), .prevAll(), .parents(), but the first argument they take is a selector that will terminate the traversal.
The .add() now accepts a context. This is primarily useful in a chain when you want to add in addtional elements (returned from an ajax request, for example) and then manipulate those in addition to the others.
The closest method can now accept a context DOMElement as a second argument. Passing in a context will typically make your closest() calls much faster. This also applies to live() which leverages closest() internally.
This returns true if there are not any properties on the object. You can only pass in objects to jQuery.isEmptyObject(), because jQuery performs an iteration on the object that is passed in without any other checks.
In jQuery 1.4, the jQuery.unique() method, which is used internally in the creation of the jQuery set, always returns results in document order. This means that jQuery sets returned from jQuery functions should be returned in document order.
For compliance with Caja and because it is slated to be deprecated in the upcoming ECMAScript 5 specification, we have removed all references to arguments.callee in jQuery core.
Now use Closure Compiler instead of YUI Min (commit)
Internal Reorganization
One of the major pushes that we made with 1.4 was towards building a more legible, understandable, code base. To achieve that we did some major restructuring of the of the code base internals and began to establish some style guidelines for the code base.
Some of the major changes that were made:
The old ‘core.js’ file has been split apart into ‘attribute.js’, ‘css.js’, ‘data.js’, ‘manipulation.js’, ‘traversing.js’, and ‘queue.js’.
The ready event has been moved into core.js (as it’s a fundamental part of jQuery itself).
The logic for css and attributes have been split and aren’t so intertwined anymore.
Testing
In jQuery 1.4 we’ve fixed 207 bugs (compared to 97 bugs in the 1.3 release).
Additionally we’ve increased our test coverage from 1504 tests in jQuery 1.3.2 to 3060 tests in jQuery 1.4.
The jQuery test suite is 100% passing in all the major browsers (Safari 3.2, Safari 4, Firefox 2, Firefox 3, Firefox 3.5, IE 6, IE 7, IE 8, Opera 10.10, and Chrome).
Backwards-Incompatible Changes
With jQuery 1.4 we attempted to minimize any large upgrade hassles – maintaining the signatures of all public functions. That being said, please read through the following list to be aware of what might cause problems in your applications.
.add() no longer plainly concatenates the results together, the results are merged and then sorted in document order.
.clone(true) now copies events AND data instead of just events.
jQuery.data(elem) no longer returns an id, it returns the element’s object cache instead.
We are now strict about incoming JSON and throw an exception if we get malformed JSON. If you need to be able to evaluate malformed JSON that is valid JavaScript, you can make a text request and use eval() to evaluate the contents.
Param serialization now happens in the PHP/Rails style by default. You can use jQuery.ajaxSettings.traditional = true; to use traditional parameter serialization. You can also set the behavior on a per-request basis by passing traditional: true to the jQuery.ajax method.
If an Ajax request is made without specifying a dataType and it is returned as text/javascript, it will be executed. Previously, an explicit dataType was required.
Setting an Ajax request’s ifModified now takes ETags into consideration.
We’ve also written a plugin that provides backwards compatibility with every potentially-breaking change that we’ve made in 1.4. Feel free to download and include this plugin, after you’ve included 1.4, if you have any issues upgrading to 1.4.
It’s the start of a new year, and the jQuery team’s been hard at work. We’ve been up day and night working to crank out the upcoming jQuery 1.4 release, and there’s a LOT to announce! So much, in fact, that we’ll need fourteen full days to get it all out there… As such, I’d like to announce The 14 Days of jQuery 1.4!
Beginning on January 14th, we’ll start a fourteen-day event. Each day we’ll have fresh videos and announcements — there’ll be code releases, project-related updates, and jQuery UI goodness, among other things. In addition to the announcements, we’ll also be releasing a set of videos over the 14 days with talks and tutorials relating the jQuery 1.4 release and other general jQuery topics. You’ll want to check back at jQuery14.com every day during the two weeks to see what’s new, or sign up to be notified via email. Think of it like an online conference, only longer, freer, and with a bit of mystery and suspense!
But Wait, There’s More!
We’ve got a lot planned for January 14th, but it seemed good to whet your appetite and pre-release some tasty jQuery morsels. Head over to jQuery14.com to learn all about the brand-new jQuery API site:
Be sure to subscribe to the jQuery14.com site or to the @jquery Twitter account for all the updates during these upcoming weeks.
Free Books, Anyone?
The jQuery project is a non-profit, open-source effort, and we rely heavily on donations and contributions to help fund everything we do. We’ll be running a fundraising drive starting now and throughout the 14 Days of jQuery. If you’re a jQuery user, show your support by making a tax-deductible donation of $20 USD or more to the project during the event, and you’ll receive a free jQuery book with your donation.
This is a change to jQuery’s selector engine that re-orders the returned results to be in document order, instead of the order in which the selectors were passed in. This change was done in order to be in compliance with the Selectors API specification (which jQuery uses, internally, in browsers that support it).
I’d like to thank Diego Perini for pushing us to get this implemented.
.live() Can Now Prevent Bubbling
It’s now possible to call event.stopPropagation() or return false within a callback and have it stop the bubbling of the live event. This means that you can now bind live events inside each other and have the inner handlers prevent the outer handlers from firing.
I’d like to thank Iraê for the solution that he proposed for this problem.
For those wondering about the, currently missing, features of .live() (like submit and change events) you can expect all of those to land in jQuery 1.3.3, due to arrive sometime next month.
:visible/:hidden Overhauled
We’ve changed the logic behind the :visible and :hidden selectors (which were used throughout jQuery to determine the visibility of an element).
This is how the logic has changed:
* In jQuery 1.3.1 (and older) an element was visible if its CSS “display” was not “none”, its CSS “visibility” was not “hidden”, and its type (if it was an input) was not “hidden”.
* In jQuery 1.3.2 an element is visible if its browser-reported offsetWidth or offsetHeight is greater than 0.
What does this change mean? It means that if your element’s CSS display is “none”, or any of its parent/ancestor element’s display is “none”, or if the element’s width is 0 and the element’s height is 0 then an element will be reported as hidden.
What is the benefit of making this switch? The result is two-fold:
* The performance is much, much, better. (See below.)
* An element is reported as “hidden” if it’s inside a “hidden” element (something that wasn’t possible before, without the use of a plugin.
I’d like to thank Matheus Almeida for proposing some of the changes that were implemented to improve the performance of these selectors.
.height()/.width() Overhauled
The width and height related selectors have all been overhauled – dramatically improving their speed in all browsers.
I’d like to thank Mike Helgeson for his contributions here which were largely responsible for some of the massive gains that we’re seeing in these methods.
Selector Speed-up in IE
The benefits of the new Sizzle selector engine are really starting to come to light as contributions from the larger JavaScript community come in. A number of additions have landed that have helped to improve the performance of the engine – especially in Internet Explorer.
I’d like to thank Fabio Buffoni for his contributions here which were largely responsible for these speed-ups.
.appendTo()/etc. Now Return Inserted Elements
This is a (minor) API change – resolving a bug in the jQuery API. The methods appendTo, prependTo, insertBefore, insertAfter, and replaceAll all now return the set of inserted elements, instead of the original set of elements.
To understand this change we need to look at a simple example.
Given the following markup, in jQuery 1.3.1 (and older) the following would occur:
This was due to the fact that .appendTo, etc. would only return the elements that were passed in to it, instead of the elements that were actually inserted (and since only a single paragraph was passed in – the first one to be inserted – only the first paragraph had the class added to it).
Thus, if you were to run the same code in jQuery 1.3.2 you would end up with:
Which is the expected result. The only catch is that appendTo, prependTo, insertBefore, insertAfter, and replaceAll all now push onto the jQuery stack (meaning that they’re affected by .end().
We did a survey of existing uses of the above methods and could find no cases where this change would affect any existing code, so we felt safe going ahead with it (especially considering that it’s the expected behavior, to begin with).
Testing
We have a couple announcements with regard to our test suite and our testing methodology in the jQuery project.
* We are now fully supporting, and the test suite is completely passing in, Internet Explorer 8rc1 and Chrome 2 (Nightly) (in addition to our normal selection of browsers).
* The test suite has broken 1500 tests (1504, to be precise).
This means that we now actively test in – and pass the test suite in – 11 browsers: Chrome 1, Chrome Nightly, IE 6, IE 7, IE 8rc1, Opera 9.6, Safari 3.2, WebKit Nightly, Firefox 2, Firefox 3, Firefox Nightly.
(We’re waiting for the next beta of Opera 10 before we begin to support it fully, there are some critical problems with the current beta.)
To measure the performance of different portions of jQuery we used a modified copy of the SlickSpeed test suite to run our tests (adapted to handle non-selector tests). The raw results for the test runs can be found below (all times in milliseconds).
Selector Tests
We used a copy of the Yahoo home page (a representatively complex web page) and used a selection of selectors that people actually use. Targeting selectors that people currently use will help to improve the performance of both existing and future applications.
The jQuery team is pleased to release the latest major release of the jQuery JavaScript library! A lot of coding, testing, and documenting has gone in to this release and we’re really quite proud of it.
I want to personally thank Ariel Flesler and Brandon Aaron who put a lot of work into fixing bugs and getting the release out the door.
Overview
There have been a number of major changes in jQuery 1.3, these are a few of the largest and most prominent changes.
Sizzle Selector Engine
jQuery has a brand new CSS selector engine – nicknamed Sizzle. We wanted an engine that was:
Faster than our current engine for the most commonly used selectors.
Fully extensible (we had to sacrifice some of our extensibility in favor of performance in past versions of jQuery).
Completely standalone.
As far as performance is concerned, we’ve done quite well, coming in about 49% faster than our previous engine:
This is especially surprising considering that the engine in 1.2.6 was already pretty fast and that we gained a great deal of extensibility in the process.
One thing that became very obvious during the development of the new engine: We wanted to be able to collaborate on it with other libraries and developers. We saw an opportunity for some solid collaboration with some of the best JavaScript developers – the result of which will help users of all libraries. For this reason we made sure that Sizzle was able to work completely standalone (no dependencies).
Additionally, as a sign of good faith and willingness to collaborate, we’ve released the source code to Sizzle to the Dojo Foundation. We wanted a common meeting ground where everyone would be able to work together and under which there would be a clear long-term copyright holder.
Right now we’re working with Prototype, Dojo, Yahoo UI, MochiKit, and TinyMCE (and many others) on Sizzle, honing it to perfection.
Live Events
jQuery now supports “live events” – events that can be bound to all current – and future – elements. Using event delegation, and a seamless jQuery-style API, the result is both easy to use and very fast.
More information about live events can be found in the .live() documentation.
When working on live events we wanted a solution that was going to be fast and scale well. To do this we needed a selector engine designed to handle delegation element filtering (roughly speaking “does this selector match this element”). The new Sizzle selector engine blew away all of our expectations – coming in almost 30x faster than our previous solution:
By using advanced filtering techniques we’re able to bring you an event delegation solution that won’t bog down your browser and will scale to dozens or hundreds of delegations on a page at a time.
jQuery Event Object
Ariel Flesler brought some serious refactoring of the jQuery event system to jQuery 1.3. The bulk of this change came down to the new jQuery.Event object. This object completely encapsulates all of the functionality normally found in a W3C-compliant event object implementation and makes it work smoothly across all browsers.
There were a number of individual changes related to the event system, as well, and those are described in-depth later on in the event section.
HTML Injection Rewrite
All of the code related to injecting HTML into a document (such as the append, prepend, before, and after methods) has been overhauled. When we were analyzing jQuery applications we found this to be one of the most common bottlenecks – and thus was in direct need for an improvement. The functionality provided is identical to what was in previous releases of jQuery but with the added benefit of being much, much faster (about 6x faster overall):
We also overhauled the creation of DOM elements (e.g. $("<script/>")) and made it identical to calling $(document.createElement("script")) (it’s both faster and saner as a result).
Offset Rewrite
Brandon Aaron felt that a full rewrite of the .offset() method was due for 1.3. Re-written from scratch, it not only handles cross-browser issues better, but does so much faster:
Seeing an almost 3x jump in performance over the offset method in 1.2.6 this rewrite is sure to make your complex interactions go that much more smoothly.
No More Browser Sniffing
The final major feature of this release is one that you probably won’t ever see or deal directly with but it’s an important change that’ll help to make jQuery last longer and with less bugs: As of 1.3, jQuery no longer uses any form of browser/userAgent sniffing internally – and is the first major JavaScript library to do so.
Browser sniffing is a technique in which you make assumptions about how a piece of code will work in the future. Generally this means making an assumption that a specific browser bug will always be there – which frequently leads to code breaking when browsers make changes and fix bugs.
Instead we use a technique called feature detection where we simulate a particular browser feature or bug to verify its existence. We’ve encapsulated all the checks that we use in jQuery into a single object: jQuery.support. More information about it, feature detection, and what this feature provides can be found in the documentation.
It’s important to note that jQuery.browser is still in jQuery – and will be for the foreseeable future (too many plugins and pieces of code depend on it). That being said we’ve deprecated it in an attempt to encourage you – and all JavaScript developers – to seriously consider using feature detection in your code.
Upgrading
With jQuery 1.3 we attempted to minimize any large upgrade hassles – maintaining all existing public APIs. That being said, please read through the list of potentially-breaking changes to be aware of what might cause problems in your applications.
Note: Many plugins are providing updated releases to coincide with jQuery 1.3. If you’re having difficulties with a particular plugin please be sure to see if a new release has arrived. Specifically both jQuery UI and the Validation plugin have updated releases that work with jQuery 1.3.
Downloading
As usual, we provide two copies of jQuery, one minifed (we now use YUI Compressor as the default minifier) and one uncompressed (for debugging or reading).
Additionally, Google has provided us with a copy of jQuery hosted on their servers. This copy of jQuery is automatically minified and gzipped – and served from Google’s fast edge cache servers.
You can feel free to include the above URL directly into your site and you will get the full performance benefits of a quickly-loading jQuery.
Changes
The following are changes that were made that may have a remote possibility to cause backwards compatibility issues in your web pages.
The ‘@’ in [@attr] has been removed. Deprecated since 1.2 this old syntax no longer works. Simply remove the @ to upgrade.
Triggered events now bubble up the DOM. Unsuspecting event handlers may accidentally capture more events than they’re expecting.
The ready() method no longer tries to make any guarantees about waiting for all stylesheets to be loaded. Instead all CSS files should be included before the scripts on the page.
.isFunction is simpler now, it no longer handles some strange edge cases (in favor of simplicity and performance).
The order of “a, b, c” style selectors may change. Browsers that support querySelectorAll (Safari, Firefox 3.5+, Opera 10+, IE 8+) will return the elements in document order, other browsers will (currently) return them in the order specified. In 1.3.2 and later release all comma-separated selectors will be returned in document order.
The trigger and triggerHandler methods no longer accept event objects within the data array. Instead they should be specified directly as an argument.
The undocumented ‘extra’ function is gone from trigger and triggerHandler functions as well.
The internal jQuery.event.trigger no longer returns the last item returned by a handler, instead it return true or false as per the W3C specification. You should use a jQuery.Event object to capture the specific return value.
You should always be sure to run your page in standards mode. There are known issues with methods not working correctly in quirks mode.
An old (deprecated) style of creating selector plugins has been removed. Previously you could create string-encoded plugins which were later turned into functions – this has been removed – please just create the functions directly.
jQuery.param(obj) execute obj’s functions instead of converting them to a String.
The following properties have been deprecated (in favor of feature detection and jQuery.support, as discussed in the Overview: jQuery.browser, jQuery.browser.version, jQuery.boxModel.
The following browsers are no longer supported: Safari 2
Performance
To measure the performance of different portions of jQuery we used a modified copy of the SlickSpeed test suite to run our tests (adapted to handle non-selector tests). The raw results for the test runs can be found below (all times in milliseconds).
We used a copy of the Yahoo home page (a representatively complex web page) and used a selection of selectors that people actually use. Targeting selectors that people currently use will help to improve the performance of both existing and future applications.
To test delegation filtering we attempted to see if a given element matched a selector. jQuery 1.3 and Prototype provided native methods for handling this (.is and .match, respectively) whereas jQuery 1.2.6, Dojo, and MooTools all used a “run a selector and see if an element is in the results” technique.
These tests analyze the performance of inserting DOM fragments (in the case of jQuery and Prototype this is HTML, for MooTools it was using their Element class). Dojo didn’t provide any explicit helpers for injecting HTML or constructing DOM elements so it was excluded.