jQuery 1.6 Released

Posted on by

jQuery 1.6 is now live and available for consumption! We’re quite proud of this release, it includes a major rewrite of the Attribute module and a number of performance improvements.

Please take this opportunity to thank members of the jQuery Team and the jQuery bug triage team for their help in getting this release out the door.

You can get the code from the jQuery CDN:

You can also get the code from other CDNs as well:

We want to encourage everyone from the community to try and get involved in contributing back to jQuery core. We’ve set up a full page of information dedicated towards becoming more involved with the team. The team is here and ready to help you help us!

In fact, we’re already getting started working on jQuery 1.7. We’re welcoming feature proposals for jQuery 1.7. If you have any suggestions please submit them using the aforementioned form.

jQuery 1.6 Change Log

All of the API changes that occurred in this release can be found in the jQuery API documentation:

Breaking Changes

In most releases we try to main compatibility with existing code. However, there are a few cases where jQuery 1.6 may require changes to existing code:

Case-mapping of data- attributes

jQuery 1.5 introduced a feature in the .data() method to automatically import any data- attributes that were set on the element and convert them to JavaScript values using JSON semantics. In jQuery 1.6 we have updated this feature to match the W3C HTML5 spec with regards to camel-casing data attributes that have embedded dashes. So for example in jQuery 1.5.2, an attribute of data-max-value="15" would create a data object of { max-value: 15 } but as of jQuery 1.6 it sets { maxValue: 15 }.

.prop(), .removeProp(), and .attr()

In the 1.6 release we’ve split apart the handling of DOM attributes and DOM properties into separate methods. The new .prop() method sets or gets properties on DOM elements, and .removeProp() removes properties. In the past, jQuery has not drawn a clear line between properties and attributes. Generally, DOM attributes represent the state of DOM information as retrieved from the document, such as the value attribute in the markup <input type="text" value="abc">. DOM properties represent the dynamic state of the document; for example if the user clicks in the input element above and types def the .prop("value") is abcdef but the .attr("value") remains abc.

In most cases, the browser treats the attribute value as the starting value for the property, but Boolean attributes such as checked or disabled have unusual semantics.

For example, consider the markup <input type="checkbox" checked>. The presence of the checked attribute means that the DOM .checked property is true, even though the attribute does not have a value. In the code above, the checked attribute value is an empty string (or undefined if no attribute was specified) but the checked property value is true.

Before jQuery 1.6, .attr("checked") returned the Boolean property value (true) but as of jQuery 1.6 it returns the actual value of the attribute (an empty string), which doesn’t change when the user clicks the checkbox to change its state.

There are several alternatives for checking the currently-checked state of a checkbox. The best and most performant is to use the DOM property directly, as in this.checked inside an event handler when this references the element that was clicked. In code that uses jQuery 1.6 or newer, the new method $(this).prop("checked") retrieves the same value as this.checked and is relatively fast. Finally, the expression $(this).is(":checked") works for all versions of jQuery.


Bugs Fixed:

  • #6481: revert $.param should treat empty arrays/objects like empty strings
  • #7881: Make compatible with XHR 2
  • #8417: When posting AJAX and the data has “??” is formats it to jQuery<timestamp>?
  • #8744: .ajax() jsonp requests are not handled correctly when hitting timeout
  • #8884: jqXHR breaks names of custom header fields


Performance Improvements

jQuery 1.6 .attr("value")

jQuery 1.6 .attr("name", "value")

jQuery 1.6 .val() (get)

Tests and Data:

.prop(), .removeProp(), and .attr()

(See the description of what’s changed in the “Breaking Changes” section, above.)

Boolean Attributes

In jQuery 1.6 Boolean attributes (such as selected, checked, etc.) can now be toggled by passing in true or false to .attr() to either add or remove them. For example:

$("#checkbox").attr("checked", true); // Checks it
$("#checkbox").attr("checked", false); // Unchecks it

Extensibility of .attr() and .val()

Two new hooks have been added in order to make it easier to add in special handling for specific attributes (jQuery.attrHooks) or form input values (jQuery.valHooks).

For example:

jQuery.attrHooks.selected = {
	set: function( elem, value ) {
		if ( value === false ) {
			jQuery.removeAttr(elem, “selected”);
			return value;

Both of the hooks behave very similarly to jQuery’s built-in CSS hooks (allowing you to specify either a get or set method for an attribute (or value)) to handle those specific cases.

Bugs Fixed:

  • #1591: IE “Invalid Argument” $(‘table’).attr(‘non-existent’)
  • #3116: .attr does not work with SVG IDLs
  • #3786: removeAttr should use jQuery.props
  • #4283: .attr(‘checked’) & XHTML 1.1 Strict
  • #4464: IE cannot get width attribute of detached IMG element
  • #4978: jQuery.prop missing cellpadding?
  • #5413: tag “img” width/height attribute is zero (IE)
  • #6562: using .attr() to set the ‘target’ attribute, with a node that has ID of ‘target’
  • #6708: Opera has inconsistent result for usemap attribute value
  • #6823: Make .val(value) faster for common use case
  • #7472: $(‘form’).attr(‘id’) return DOM Element
  • #7485: Inconsistency between has [attribute] selector and attr() method
  • #7709: Permission denied to access property ‘nodeType’ from a non-chrome Firefox/3.5.15
  • #7996: Safari $(‘script’).attr(‘event’); Bug
  • #8117: .removeAttr don’t works with select element’s size attribute
  • #8150: removeAttr issue in webkit, firefox
  • #8255: support for list attribute
  • #8418: set name parameter using attr() method in IE 7
  • #8457: attrHooks
  • #8570: .val method returning “on” for dynamically created radio buttons in ie9
  • #8699: .attr() returns -1 on missing attribute instead of undefined
  • #8772: Using .attr() to set input type ‘range’ causes script error in IE9
  • #8997: new attribute “form” (HTML5) is not supported, .attr(‘form’) not working properly
  • #9037: $(‘blah’).attr(‘onclick’) return event in Firefox


Bugs Fixed:

  • #8854: Bug in minifier process


jQuery.map( Object )

It’s now possible to map the properties of a JavaScript object using the jQuery.map method. For example:

var counts = { first: 1, second: 2 };
counts = jQuery.map( counts, function( value ) {
	return value++;

Bugs Fixed:

  • #2616: A better jQuery.map
  • #4366: $.each fails in IE with document.styleSheets
  • #6690: Store references to location and navigator objects
  • #7049: making jQuery.noConflict() callable anytime
  • #7783: Fixing $.proxy to work like (and use) Function.prototype.bind
  • #7862: jQuery.globalEval(): Execution Delayed By Remote Scripts in Firefox
  • #7990: Script space quota exhausted error when creating a large HTML block with jQuery constructor in Firefox
  • #8893: jQuery.proxy( context, name ) bug in 1.6b1
  • #8984: jQuery doesn’t parse html from string correctly!
  • #8993: jQuery.map( emptyNodeList ) enumerating properties.


Relative CSS

We’ve ported the functionality from the .animate() method, giving you the ability to update CSS properties using relative values. You can now prefix a CSS value with “+=” or “-=” to update the property relatively, in relation to the current value.

// Move an item 10px over
$("#item").css("left", "+=10px");

Bugs Fixed:

  • #6135: jQuery tries to access the .style attribute of text tags
  • #7345: Support relative values for $().css()
  • #7730: offset.js: setOffset uses parseInt to parse css values which may contain floating point numbers
  • #8401: minor enhancement to opacity cssHooks
  • #8402: jQuery.cssProps is useless in all browsers but IE6/7/8
  • #8403: jQuery Bulldozes Other IE Filters When Assigning Opacity


Performance Improvements

Large performance improvements to .data() were achieved by improving the performance of event triggering. jQuery’s .data() method triggers getData and setData events which allow for greater levels of extensibility for plugins, improving how they’re triggered allows .data() to become even faster.

jQuery 1.6 .data() (get and set)

Tests and Data:

Bugs Fixed:

  • #7328: Should data-foo-bar be accessible via .data( ‘fooBar’ ) as well as .data( ‘foo-bar’ )



In 1.5, when you wanted to take the exact same action whether a deferred was resolved or rejected, you had to use a named function and pass it to “then” twice:

function callback() {
    // the deferred has been resolved or rejected

defer.then( callback, callback );

With “always”, you can do it inline:

defer.always(function() {
    // the deferred has been resolved or rejected


Chaining asynchronous tasks can be tedious, especially when you want to return a Promise for the whole chain:

function chainedAjax( url ) {
    return $.Deferred(function( defer ) {
        $.ajax( url ).then( function( url2 ) {
            $.ajax( url2 ).then( defer.resolve, defer.reject )
        }, defer.reject ).promise();

With “pipe”, everything is much more readable and natural:

function chainedAjax( url ) {
    return $.ajax( url ).pipe(function( url2 ) {
        return $.ajax( url2 );

It can also be used to filter resolve and/or rejection values:

var request = $.ajax( url ).pipe(function( data ) {
   return data.value;

request.done(function( value ) {
    // we get the value field of the original response


Synced Animations

In jQuery you can have multiple animations running simultaneously (even multiple on the same element, animating different properties). In 1.6 we’ve introduced an enhancement that ensures that all animations are synced to the same timer interval. This had the potential to create problems before as animations could become slightly out-of-sync (even by a couple milliseconds) resulting in slightly “off” animations.

Smoother Animations

Additionally jQuery is now using the new requestAnimationFrame method provided by browsers to make our animations even smoother. We can use this functionality to avoid calling timers and instead depend upon the browser to provide the best possible animation experience.


Just like $.ajax() before it, $.animate() gets “deferred”. jQuery objects can now return a Promise to observe when all animations on a collection have completed:


$.when( $(".elements") ).done(function( elements ) {
    // all elements faded out

Bugs Fixed:

  • #7917: .animate() when used with large groups of elements is not “in sync”
  • #7934: $.fn.animate to implement deferreds
  • #7974: Cleanup effects.js to improve performances and reduce filesize
  • #8099: SPAN element becomes block level on show()
  • #8101: use requestAnimationFrame instead of setInterval for animations, when available


Performance Improvements

(As mentioned while discussing .data() performance, the performance of event triggering has been improved.)


jQuery provides a mechanism for delaying the execution of the ready event (primarily for plugin authors). The API for this mechanism has been improved in 1.6, resulting in a single, simple, method:

jQuery.holdReady( true ); // Pause execution of ready event
// later...
jQuery.holdReady( false ); // Resume execution

Bugs Fixed:

  • #5884: live mouseenter/mouseleave events don’t fire as expected when nested
  • #6514: Mouseenter and mouseleave events not able to be triggered if bound by live
  • #6913: namespaced event bubbleing wrong
  • #6993: .bind() and .one() don’t allow a function as data
  • #7071: Accessing the ‘type’ property on VML elements fails on IE
  • #7883: .delegate (and .live) should accept false as the fn arg, like .bind
  • #8018: Unsafe access to frameElement causes error in crossdomain (i)frames
  • #8272: Exceptions in plain JS object event handlers swallowed by jQuery
  • #8712: Custom events don’t bubble up to window
  • #8732: Incorrect feature detect for IE9 focusin/focusout
  • #8753: jQuery 1.6: jQuery.Event contstructor to support setting properties
  • #8755: binding to beforeunload throws an error in IE6, 7, 8 on page unload
  • #8777: jQuery 1.6: undelegate() accepts custom namespaced events
  • #8788: Reorganize jQuery.event.trigger to use loop instead of recursion
  • #8790: Optimize non-attached events such as data events
  • #8803: jQuery.holdReady() method


Bugs Fixed:

  • #1954: val() returns innerHTML for button elements in IE
  • #6180: jQuery.clean should not touch script tags that are not of type text/javascript
  • #7623: Exception thrown in replaceWith
  • #7885: jQuery .offset doesn’t property works when current offset is float (which is possible in FireFox)
  • #8060: Setting checked to true on a disconnected checkbox does not carry over after attaching to DOM.
  • #8500: radios and checkboxes revert to default (HTML) state when wrapped in IE


Bugs Fixed:

  • #8203: Remove un-needed “someVar = null;”s
  • #8851: Wraps strings with double quotes in sources and tests
  • #8882: Tests: Update QUnit usage, replace id=main with id=qunit-fixture


Bugs Fixed:

  • #7931: scrollTop and scrollLeft setters return null when called on empty jquery object


:focus Selector

In jQuery 1.6 we now ensure that the :focus selector works properly across all browsers. You can use this selector to find the currently focused element on the page (such as a form input).

  • #3685: Selector fails for forms with an element named “name”
  • #4321: $(“#”) returns undefined
  • #8105: :focus selector filter


Bugs Fixed:

  • #9028: IE8 crashes while loading 1.6rc1 if using body background image


find(), closest(), and is() now all take DOM elements and jQuery objects

In jQuery 1.6 we’ve ensured that find(), closest(), and is() can all take DOM elements and jQuery objects as arguments. This gives you alternatives for filtering sets of elements based upon the passed-in elements.

// Only returns .test elements if they're inside of a div
$("div").find( $(".test") )

Bugs Fixed:

  • #2773: $.fn.is and $.fn.not should accept DOMelements and jQuery collections
  • #5712: Allow jQuery.fn.is to accept a function
  • #6912: $().add(selectElement) adds option children instead
  • #7369: $(‘<div>ff</div>’).closest(‘[attr]’); raises exception in all browsers
  • #8609: Result of .find(” “) is undefined

68 thoughts on “jQuery 1.6 Released

  1. berdgfdg on said:

    the problem with the attr change is that it broke 3rd party plugin as well as our own code, which we have less control over.

  2. haki on said:

    That .pipe() , .css(“left”;”+=10px”) , .hoodReady , .map() and all that other stuff blow me completely away! I am looking foreward to integrate all that stuff in my codes! BIG THX guys!

  3. OMG very bad with the new “prop” and “attr”…

    Every actual third party plugin is broken with 1.6, every code-row has to be reviewd in every project.

  4. Patrick Corcoran on said:

    It seems that className no longer works when set on an empty object.

    $(”, { className: ‘foo’ })

    used to create a , but now it creates a , which of course is broken. No mention of this above.

    $(”, { ‘class’: ‘foo’ })

    does work as expected.

  5. Patrick Corcoran on said:

    It seems that className no longer works when set on an empty object.

    $(‘<div/>’, { className: ‘foo’ })

    used to create a <div class=”foo”>, but now it creates a <div classname=”foo”>, which of course is broken. No mention of this above.

    $(‘<div/>’, { ‘class’: ‘foo’ })

    does work as expected.

  6. Denis on said:

    The .attr() vs .prop() thingy is a bit stunning imo. It could equally have been .attr() vs .tagAttr() or something like that without introducing any back-compat issues.

  7. RobG on said:

    It seems to me a better decision would have been to introduce getAttr(), removeAttr() and getProp(), removeProp() so that attr() could be deprecated for this release and removed later (1.7, 2.0, whatever). That would give everyone a while to convert their code to the new API.

    It also means the methods are self explanatory, whereas the new attr() and prop() may still be confused as being both setter and getter per the original attr().

  8. Hi!

    I’m used to this library for a long time and track this throught each version.
    And the problem in this version is conflict with csshover.htc debug for ie6, that seem to not effects.
    Any one who used to csshover.htc has same problem with me?


  9. Trian Karayiannis on said:


    The differentiation between .attr() and .prop() should have had a smoother migration path. I have built an entire framework on top of 1.4.x and multiple apps on top of it and with jQuery 1.6 it means I’ll have to rewrite the whole shebang if I want to upgrade (which I was looking into in order to explore if some bugs in 1.4.x are fixed).

    Nice, folks, really nice… Thank you for that!