jQuery 1.8 RC1 Released

Posted on by

jQuery 1.8RC1 is here. Yep, RC as in Release Candidate. The good news is that this release is a few days later than I expected it to be. It’s good news because we received several valuable but last-minute bug reports we were able to fix. Many thanks to those of you who took the time to try out Beta 2 with your code, and especially to those who found and reported bugs.

Now I know there are a lot of you out there thinking, “Gee whiz, nobody ever lets me find bugs.” Well, here’s your chance to be a hero to the jQuery community. In this Release Candidate we may have taken some working features and inserted problems so obscure that even we don’t know where they are. Please find them! Just grab the code from here:


Try out this Release Candidate code wherever you use jQuery, and let us know about any issues you find via the bug tracker. Be sure to mention you’re testing against jQuery 1.8 RC1, and please create a test case that shows the bug using jsFiddle.net so we can reproduce it and investigate. You can use the “jQuery (edge)” choice for framework in jsFiddle, which represents the most up-to-date code.

Oh, and did I mention this is a Release Candidate? Yeah, I did. Who knows if there will ever be a jQuery 1.8.1? If you find a bug after we release jQuery 1.8, it could be six months before it’s fixed. Six months of misery, all because you didn’t test the Release Candidate! One and a half women could make a baby while you’re waiting for that critical bug fix! For your own sake, please try it out!

jQuery 1.8rc1 Change Log

The current change log of the 1.8rc1 release.


  • #8205: JSONP random result is causing memory leak in IE8
  • #8653: jQuery.param outputs "null" and "undefined" in the query string
  • #9399: Deprecate jqXHR.success and jqXHR.error
  • #10285: evalScript rcleanScript replacement fails in IE8
  • #10524: jQuery.fn.load does not merge data parameter with jQuery.ajaxSetup
  • #10944: $.ajax does not always return an object implementing the Promise interface
  • #11013: Deprecate use of Deferred/Promise with sync $.ajax
  • #11402: evalScript function fails with error error 80020101 in IE
  • #11743: jQuery silently ignores errors during script tag ajax request in $.appendTo()
  • #11778: Cached XHR requests should still resolve asynchronously
  • #12122: jQuery.ajax() async deprecate use with $.Deferred


  • #11153: jQuery 1.7 Strips Carriage Returns in IE 8
  • #11212: Sizzle.getText converts unbreakable space into whitespace on IE
  • #11547: XML DOM .removeAttr() doesn't remove cased attributes
  • #11962: Standardize getter return values for empty sets.
  • #12127: Clone does not correctly copy checked state in IE10


  • #11767: Support custom build without effects
  • #11789: Update README to describe grunt build system
  • #11856: modularize dimensions
  • #11857: modularize css
  • #11865: modularize offset
  • #11965: Create deprecated.js to contain as much of the deprecated stuff as possible


  • #10657: Deprecate jQuery#size() in favor of jQuery#length
  • #11290: selector interpreted as HTML
  • #11470: Adding a builtin readyP promise
  • #12018: $(document).ready() fires too early in IE8
  • #12026: Let $(html, props) use any jQuery.fn method


  • #10373: `document.defaultView` => `window`
  • #10413: width, innerWidth, innerHeight, outerWidth, outerHeight are inaccurate for a "box-sizing: border-box" child of hidden parent
  • #10679: CSS3 vendor prefix support
  • #11004: getWH incorrectly removes padding and border width when box-sizing is border-box
  • #11787: Remove jQuery.curCSS
  • #12088: Webkit now returning percentages for more getComputedStyle properties
  • #12148: hide event don't fire when toggle


  • #7579: jQuery.data() truncates numbers taken from data-xxx attributes
  • #10589: Remove $.fn.data("events")


  • #11010: Make Deferred.then == Deferred.pipe like Promise/A
  • #11011: Allow traditional options object for $.Callbacks flags
  • #11736: Remove Deferred .isResolved() and .isRejected()
  • #11749: Preserve context objects when multiple Deferred object are passed to $.when()


  • #6724: wrong $(window).height() in mobile safari (iphone)
  • #10877: Make outerWidth/Height a setter
  • #11293: Reading width or outerWidth of empty TDs alters columns width values
  • #11604: Switch $(elem).width(-val) from no-op to $(elem).width(0)
  • #11724: $(document).height() changed in Firefox 12


  • #7109: animate width starts with invalid width on webkit
  • #7157: Animation callback shows element is still ":animated"
  • #8387: flickering problem with jQuery 1.5 hide/show issue with inline and inline-block elements on webkit browsers
  • #8627: .animate() fails on letterSpacing in IE (regression in 1.5.1)
  • #8892: Callback is raised before objects are shown with fadeIn() and jQuery.fx.off = true
  • #9217: javascript error in IE8 when animating element is removed before animation finishes
  • #9505: animate() issue when mixing percentages and pixels in WebKit
  • #11635: Explicit overflow:auto is overridden by inline overflow:hidden during animation
  • #11755: animate and it aliases should not use :hidden selector
  • #11797: New animation related events
  • #11854: percentage animations jump to end
  • #11971: Animating background-position fails in IE8
  • #11999: Incremental animation on fixed div does subtraction instead of addition in Chrome.
  • #12117: overflow hidden not properly set when animating to 0 height or width
  • #12150: border-spacing property accumulates when rows are shown and hidden


  • #8545: Leak with events in IE
  • #10067: Firing $.ready on document.readyState === 'interactive' too
  • #10895: The doScrollCheck ie hack in bindReady degrades ie7 performance for no reason whatsoever
  • #11101: Deprecate "exclusive" events option from trigger method
  • #11315: Problems with delegate() and :first in nested elements with equivalent classes
  • #11328: Ctrl key doesn't set event.metaKey to true on Windows
  • #11382: Mouseenter doesn't fire on a disabled input element
  • #11500: Bug : "change" event handler not executed when triggered manually on IE7 & IE8
  • #11621: Triggering a event on document doesn't bubble to window
  • #11718: Deprecate .data() events
  • #11719: Deprecate .bind("ready") event
  • #11731: Deprecate "hover" pseudo-event
  • #11733: Deprecate .load(), .unload(), and .error() methods
  • #11764: Allow delegated non-native events on disabled elements
  • #11786: Deprecate .toggle( handler, handler, … ) signature


  • #8894: appendTo() and alike methods called after clone() returns incorrect jQuery set in IE
  • #10324: Clone does not copy innerHTML of object element in IE9
  • #11231: Append, Prepend, After, Before should accept an array as first argument
  • #11338: Inconsistent behavior with .replaceWith() and disconnected nodes.
  • #11528: ie8 serialization bug with .html() also hitting html5 tags
  • #11566: node.append et al. does not work when node is a DocumentFragment
  • #11617: Define a $.parseHTML method for creating HTML fragments
  • #11809: Memory leak in .text(val) setter?
  • #11898: prevAll() with a complicated :not() selector returns results in wrong order
  • #12132: IE10 bug when cloning an object element without a parentNode


  • #10996: Simplify offset()
  • #11823: Remove webkitConvertPointFromNodeToPage


  • #3778: selector matching issues
  • #5568: Selectors behave differently with comments tags on FF/IE
  • #7596: xpath selector attribute name with brackets [] fails
  • #8473: In IE9rc *[tabIndex] select all elements without tabindex also
  • #8906: .(prevAll('span:has(input,select,textarea)')
  • #9400: Deprecate :text, :radio, :checkbox, etc. selector extensions
  • #9810: Rewrite Positional Selector Logic
  • #10003: Regression/BC break from #6963
  • #10074: Chaining two [] selector with :first not working
  • #10499: :nth-child() inside :has() treated as if outside it
  • #10570: :text selector throws an error in IE7 when there is a cross domain iframe on the page
  • #10697: Sizzle revamp
  • #10799: Inconsistent results with [name="name"] selectors (also breaks .has)

jQuery 1.8 Beta 2 Released

Posted on by

It’s been a crazy few weeks around jQuery Central, what with the release of Beta 1 and the jQuery Conference in San Francisco following that. Fear not! Between all the travel, conferences, meetings, and blog posts about the future of jQuery, we’ve actually managed to write some more code. As proof, here is jQuery 1.8 Beta 2:


This is the critical section in the program where we call on you, the jQuery community, to help us bring this one home. Use Beta 2 with old browsers, new browsers, red browsers and blue browsers. (That’s IE6, Chrome Canary, Opera, and Internet Explorer, respectively.) Test this file with all your code, please test it well in every mode. Did something break in Beta 2? Please tell us now before we’re through!

With assistance from those of you who tested Beta 1, we found a few bugs and squashed them. We can’t emphasize enough how important it is for us to get feedback from you as you test with these beta versions. We don’t like releasing final versions that cause problems when you drop them into your web pages, and the way to prevent that is to test with the beta and let us know about problems in advance.

NOTE: This release required coordination with jQuery UI to fix a few problems. For that reason, pages using jQuery UI will need to include the latest UI master version to test against jQuery 1.8b2. You can get it here: http://code.jquery.com/ui/jquery-ui-git.js. There will be a maintenance release of jQuery UI 1.8 that includes jQuery core 1.8 support, but users are encouraged to update to jQuery UI 1.9 when it is released.

If you find a problem, please try to reduce it to a simple test case. jsFiddle is our preferred way to get test cases, since it allows us to tweak the test case, diagnose the problem, and explore solutions. (Select jQuery (edge) for the framework, which is the latest code.) With test case in hand, head over to the bug tracker and let us know what happened. Thanks!

In addition to bug fixes reported in Beta 1, this new beta also has a significant rewrite of the Sizzle engine for even better performance. It fixes a big pile of bugs related to IE 6, 7, and 8 and makes those browsers more consistent to use. Perfection with oldIE will always be an elusive thing, but we’re still trying to make your development life as easy as possible no matter the browser.

If you build your own custom versions as described in the README file on Github, you now have the option of leaving out some of the deprecated functionality that will be removed in future versions. We’ll be adding to this file as we isolate additional deprecated functionality.

Below is a complete list of the changes since jQuery 1.7.2.

jQuery 1.8b2 Change Log

The current change log of the 1.8b2 release.


  • #4624: Charset in default ajaxSettings.contentType
  • #10978: jQuery.param() should allow non-native constructed objects as property values
  • #11264: evalScript() uses defaults set by ajaxSetup()
  • #11426: jQuery.ajax() always fails when requesting JPG images in IE


  • #5571: Allow chaining when passing undefined to any setter in jQuery
  • #10828: attr("coords") returns undefined in IE7
  • #10870: Incorrect behaviour of $.removeAttr("selected")
  • #11316: Consider looking through valHooks by element type first, then by nodeName instead of the other way around


  • #10692: Configure the jshint options to more accurately match the style guide
  • #10693: generalize the "test something in an iframe" code in unit tests
  • #10901: have unit tests fail if the tester is running from file:// or doesn't have PHP
  • #10902: ability to test a built version of jQuery in unit tests
  • #10931: Unit tests shouldn't require internet access


  • #10466: jQuery.param() mistakes wrapped primitives for deep objects


  • #10639: outerWidth(true) and css('margin') returning % instead of px in Webkit
  • #10754: have jQuery.swap return the return of the callback instead of just executing it
  • #10782: Incorrect calculating width
  • #10796: Bug in IE7 with $('#el').css.('background-position')
  • #10858: css.js regular expressions are incomplete
  • #11119: The curCSS function only need 2 arguments


  • #11309: hexadecimal-formatted data-* attributes parsed incorrectly


  • #11306: calling .disable() or .lock() on a $.Callbacks object breaks its fired() status


  • #8498: Animate Hooks
  • #10006: method show is not working as expected in all browsers when called for document fragment
  • #10848: Animation toggling loses state tracking in certain atomic edge cases
  • #11415: Silently ignore negative CSS values where they are illegal
  • #11469: Negative margin in animations (.animate)


  • #8165: .live('click', handler) fires on disabled buttons with child elements in Chrome
  • #10819: Eliminate "this.on.call(this, "
  • #10878: $("select").live("change", function(){ …broken in IE8 in jQuery 1.7
  • #10961: Error in XRegExp using jQuery 1.7.1 in IE6-9
  • #10970: The .on() selector parameter doesn't work with :not(:first) selector
  • #10984: Cannot off() custom events ($.event.special)
  • #11021: Hover hack mangles a namespace named "hover"
  • #11076: .clone(true) loses delegation filters
  • #11130: jQuery.fn.on: binding map with null selector ignores data
  • #11145: $(document).on() not working with name="disabled"


  • #9427: Passing undefined to .text() does not trigger setter
  • #10753: inline the evalScript function in manipulation.js as it's only used once
  • #10864: text() method on a document fragment always returns the empty string
  • #11055: Update HTML5 Shim elements list to support latest html5shiv
  • #11217: Append problem with webkit
  • #11291: Cloning XMLDoc's with HTML5 nodeName's breaks on IE
  • #11323: script tags with type="text/ecmascript" leak into the DOM
  • #11356: safeFragment memory leak


  • #10952: .fired() doesn't work on Callbacks object when it is flagged with "once"
  • #11257: Wrong path to source files in test suite if PHP missing


  • #10967: .promise() does not attach methods onto target


  • #7986: Bug in $.support.boxModel if page has DIV-element CSS
  • #11048: Support Tests affect layout for positioned elements in IE6-9
  • #11337: Bug in $.support.reliableMarginRight


  • #11370: $('<div>').siblings() throws exception

The New Sizzle

Posted on by

In order to make your 4th of July more sizzlin’ (you’re welcome), the jQuery team is happy to announce that Sizzle, jQuery’s CSS selector engine, is better, faster, and more reliable than ever! Sizzle has received a substantial rewrite to be included with the release of jQuery 1.8.

First, credit should be given to Diego Perini for pointing me in the right direction as well as Samuel Lebeau for creating a project 3 years ago called Bouncer, a “fast bottom-up element matcher for Javascript”.

jQuery, along with Sizzle, was released in 2006, about 3 years after Simon Willison came out with getElementsBySelector, which pretty much set the stage for every selector engine we have today. As time went on, Sizzle was rewritten a few times for the sake of performance and more and more bugs were covered as the number of people using it increased.

During this time, other quite impressive selector engines were introduced, including but not limited to NWMatcher (by Diego), dojo.query, Slick, base2, qwery, and YUI. Though they all have their own strengths, NWMatcher and Dojo particularly stood out as exemplary engines. While neither is the fastest at every selection, they are both consistently fast for almost every selector. My goal was to achieve this same level of performance for Sizzle, retain all of the edge-case bug fixes that John and the bugs team have collected over the years, and cover even more bugs that were in the queue or were covered by other engines. I can now safely say this goal has been reached.

While I won’t say Sizzle is completely bug free or it is always the fastest in every situation, the reliability and performance gains are very competitive. http://jsfiddle.net/timmywil/s7rN4/ is a primitive test used to quickly observe the differences between some selector engines for several selectors (should be run in a browser with a console open).

What changed

Below is a reduced list of the main code differences between Sizzle in jQuery 1.7.2 and jQuery 1.8.

One compiled selector function

The selector parser compiles a selector into one function containing functions for each part of the selector. This means that for any given selector (excluding positional (POS) selectors such as :first or :eq(3)), the possible set of elements need only be checked once. This is predominantly where the major speed boost and heightened stability comes from.

Additionally, Sizzle maintains a cache of the most recently compiled functions. The cache has a maximum size (which can be adjusted but has a default) so you don’t get out-of-memory errors when using a lot of different selectors.

Note: this does not have an effect on simple selectors (ID-only, TAG-only, CLASS-only) because Sizzle has had shortcuts for these that defer to getElementByID, getElementsByTagName, and getElementsByClassName whenever possible. That wasn’t changed (except for the addition of a shortcut for element-rooted ID selectors), and those are still the fastest selectors. Any other selector will go through querySelectorAll if available or run through the compiler.

querySelectorAll and matchesSelector

With this latest rewrite, the code paths to querySelectorAll and matchesSelector are even better than before and yield excellent performance.

Some people ask why we need Sizzle at all, since modern browsers have querySelectorAll and matchesSelector and accept a wide range of CSS3 selectors. The problem is that every browser (not just IE) has a few bugs in these methods. Selector engines must know beforehand what these bugs are and bypass these methods before they return incorrect results (though not all of them do). Sizzle now has this covered.

In addition, querySelectorAll and matchesSelector do not know how to process jQuery selector extensions such as [attr!=value]. Any time you use a selector extension, Sizzle needs to handle the selection natively.

Improved selector validation

Validating selectors is a tricky business. To be too strict can be annoying, but to be too flexible can produce unexpected results. In the past, Sizzle has been both of these at different times for several use cases. The most recent changes are geared towards adhering to the W3C selectors specification as much as possible, but also allowing some things that the spec does not (such as having complex selectors within a :not() pseudo).

Specifically, we are matching all whitespace characters where necessary, including line feed, tab, carriage return, and form feed(http://www.w3.org/TR/selectors/#whitespace), validating identifiers and operators in attributes selectors (http://www.w3.org/TR/selectors/#attribute-selectors), and providing a character encoding that matches the spec (http://www.w3.org/TR/css3-syntax/#characters).

Combinators (space, ~, >, +)

Combinators can get very complicated, but the new strategy handles these with great poise. In the release of jQuery 1.8 beta (and at the jQuery conference this year), I claimed that Sizzle had improved support for combinators. While the accuracy was improved, I spoke too soon and, fortunately, this was pointed out by someone I only know as Yaffle on github. Apparently, for very large and deep documents, the original revisions were checking so many elements that it was causing a stack overflow for selectors that had several combinators. For each combinator, the number of elements checked went up exponentially in order to maintain possible matches. This was bad. Sizzle now takes care of that issue and gets very satisfying results.


Although most of the old API for Sizzle was not changed in this rewrite (except for the removal of the now unnecessary Sizzle.filter from the private API), there are a couple changes that make Sizzle even more extensible. The most common way to extend Sizzle is to add custom pseudo selectors. Now with the parser compiling a function of functions, you can receive more information when creating your custom selector. For example, within Sizzle, the implementation for the :not pseudo selector is very similar to

// Using the createPseudo function tells the compiler
//   to pass the pseudo argument, context, and whether the current context is xml
//   to the function passed to createPseudo and trusts
//   that a function to be used for filtering will be returned.
// Note: the use of createPseudo is only necessary for creating custom
//   pseudo selectors with arguments.
Sizzle.selectors.pseudos.not =
    Sizzle.selectors.createPseudo(function( selector, context, isXml ) {
        var matcher = Sizzle.compile( selector, context, isXml );
	return function( elem ) {
		return !matcher( elem );

This is the only breaking change in the public API given the new parser, but I think creating custom pseudos with arguments is now much cleaner. For more information, please refer to the Sizzle docs.

Perhaps some of you are thinking that it could be nice to pre-compile your own selectors. Well, you can. Sizzle.compile is exposed so you can cache your selectors before they get used. While compiling is still very fast without caching, you can make sure that step is skipped before the selection is ever run. Call compile with your selector and context

Sizzle.compile(“my>long>complicated:selector(poof)”, document);

and it’s added to the cache. You can even increase/decrease the size of the cache by setting Sizzle.selectors.cacheLength.

Note: The majority of users do not need to use the compiler as Sizzle will maintain a cache of recently compiled selectors. Overriding Sizzle.compile will have no effect on Sizzle as it maintains an internal reference to this method.

Get the code!

The code is now available in the git versions of jQuery and Sizzle. Expect jQuery 1.8 to be released sometime this month. Issues specifically for Sizzle can be filed on GitHub and, as always, any issues related to jQuery as a whole can be filed on our bug tracker. Try it out for yourself and let us know if you run into any problems. Enjoy and Happy Independence Day!

jQuery 1.9 and 2.0 — TL;DR Edition

Posted on by

It seems that many people had questions and misconceptions about the last post, so let’s try a short Q&A format to answer some of the comments left there.

Why is the jQuery core team dropping support for oldIE (IE 6/7/8)? We’re not! jQuery 1.9 will support oldIE when it’s released next year. The jQuery team will continue to support and maintain version 1.9 even after jQuery 2.0 is released.

Why are you making me use conditional comments to include jQuery? We’re not! You can use jQuery 1.9 for all the browsers we support, from IE6 all the way up to the latest versions of Chrome, Safari, Opera, or Internet Explorer.

What happens when jQuery 2.1 is released and adds APIs, will jQuery 1.9 support them? Can we borrow your crystal ball? jQuery 2.1 isn’t likely to arrive until 2014, so it’s hard to say what jQuery 2.1 will look like as we sit here in the middle of 2012. Our general goal is to keep the 1.x and 2.x lines in sync and add functionality via plugins; see the keynote from last week’s conference.

How long will you support jQuery 1.9? As long as oldIE is a significant factor on the web. It’s even possible that there will be further releases in the 1.x line, but we haven’t yet received the crystal ball requested in the previous question. When Microsoft drops Windows XP support in April 2014, however, it will put a hurt on the oldIE installed base.

I still have a lot of IE8 users, can’t you just drop IE6 and IE7? The oldIE browsers share many of the same flaws, so it doesn’t help to do anything less than remove all three in jQuery 2.0. If you need oldIE support of any kind, a supported jQuery 1.9 will be right there for you.

My website is in China and 22 percent of our users are still using IE6! Seems like some sort of human rights violation. Oh, and that wasn’t a question.