Hacker News new | past | comments | ask | show | jobs | submit login
JQuery 1.6 released (jquery.com)
320 points by potomak on May 3, 2011 | hide | past | web | favorite | 41 comments



This release causes Internet Explorer 6 to freeze just by including the script in the page. This is a non-starter. I'll submit a bug report about it later today, just thought you guys would like to know in the meantime.

EDIT: It looks like the freeze on IE6 might be caused by FancyBox (http://fancybox.net/ ). Though it didn't freeze with any previous version of jQuery.


A reduced bug report would be good. We haven't seen any reports of this elsewhere (and the jQuery test suite runs to completion in IE 6) so I'm not entirely sure what could be happening here. Any insight you can provide (and a bug report) would be appreciated.


Simple reproduce case:

  <html>
  <head>
  <script src="http://code.jquery.com/jquery-1.6.min.js"></script>
  </head>
  <body>
  <script>
  $('body').append(
    '<span></span>',
    '<span></span>',
    '<span></span>'
  )
  </script>
  </body>
  </html>
The bug is in this block: https://github.com/jquery/jquery/blob/1.6/src/manipulation.j...

Note the inner loop is clobbering the outer loop's "i" variable.


Oof! That's no good, at all. We'll fix this right away. Thanks for the reduction. Just filed it here: http://bugs.jquery.com/ticket/9072


The issue has been fixed and integrated into the current build of jQuery: http://code.jquery.com/jquery-git.js

We're going to have a 1.6.1 release within the week. Thank you for your bug report!


He gets a reward!

http://rewardjs.com/


Fantastic find, crescentfresh! Changing "i" to "j" in the inner loop fixes the problem on IE6.

Now we just have to wait for jQuery 1.6.1.


In the future, please post any jQuery bugs you happen to find in the jQuery Bug Tracker http://bugs.jquery.com/

This helps us to help you! And remember, the future in San Dimas is excellent... so be excellent to each other.


I wasn't entirely sold on the splitting up of attributes and properties at first. After all, a big part of jQuery is adding convenience, and this does remove a certain amount of convenience at the end of the day, even if only a little. Then I got to the performance graphs at the end. Those are some impressive speed ups for almost all the browsers (1). The speed + more logical separation seems totally worth it.

(1) Except, you know, ie 7 and ie 8. So... half the internet.


I'd prefer the convenience, as I have yet to code up some jquery and think "damn, .attr is a dog", and now I have to refactor a bunch of code before I can upgrade, and the reality of it is that I won't. jQuery is awesome, but this is the first release that I've not wanted to jump all over


I thought about this discussion a lot more today, discussed the points with the rest of the jQuery core team, and we decided to land an improvement to bring back the boolean attribute handling (with virtually no performance overhead).

The bug and commit are as follows: http://bugs.jquery.com/ticket/9079 https://github.com/jquery/jquery/commit/a9d9f8c5422f171d9c45...

You can start using this code right now with the following version of jQuery: http://code.jquery.com/jquery-git.js

Hope this helps!


Trying to get some clarity around this commit. As I understand it this addresses usecases where an element's boolean property is set to true, and .attr() is called as a getter for said property, correct?

Eg

  $(optionElement)
    .prop('selected', true)
    .attr('selected'); // undefined in 1.6, "selected" in 1.6.1


Let's pretend we're working with a checkbox that isn't checked at all:

    <input type="checkbox" id="c"/>

    $("#c").attr("checked") => false     // 1.5.2
    $("#c").attr("checked") => undefined // 1.6
    $("#c").attr("checked") => undefined // 1.6.1
The user then checks the checkbox OR we set the check by doing .prop("checked", true) OR we set the check by doing [0].checked = true, the result would be:

    $("#c").attr("checked") => true      // 1.5.2
    $("#c").attr("checked") => undefined // 1.6
    $("#c").attr("checked") => "checked" // 1.6.1
Note that if we had done .attr("checked", "checked") OR .attr("checked", true) to set the checked property then .attr("checked") would've returned "checked" in both 1.6 and 1.6.1.

In short: In jQuery 1.6.1 .attr(BooleanAttribute) now returns either the name of the attribute (if true) or undefined (if false). Which is consistent with the rest of the API and with the DOM itself.

I should note that all of this is a moot point if you're using .prop("checked") - that will just return true/false consistently based upon the current checked state of the checkbox.


Which changes (I assume, to .attr()) are affecting you, in particular?


Yes, I've since read other comments and have a better understanding of the reasoning behind .attr and .prop, so I'm a little less bah-humbug about having to refactor before upgrading. It appears that search/replace .attr('value') => .val(), .attr('checked') => .prop('checked') are the big offenders, but probably need to look closer at .attr('enabled') and .attr('disabled') as well.


Relying on the following attributes as returned from .attr() will break, and should get ported to use .prop() instead: 'checked', 'disabled', 'readonly', 'selected' (for <option>s), 'multiple' (for <select>s), 'ismap' (for <img>s), 'defer', 'noresize' (for <frame>s), 'nowrap'.

List compiled (partially) from http://stackoverflow.com/questions/706384/boolean-html-attri...


This should be linked to or listed directly in the OP.

Really, most people reading the changelog care about "how do I make my existing code work with this"--and the details listed are conceptual, but not all practically relevant.


I have this code:

  $.fn.setAttr = function(attr, bool) {
    if(bool)
      this.attr(attr, attr);
    else
      this.removeAttr(attr);

    return this;
  }

  $.fn.disabled = function(bool) {
    return this.setAttr('disabled', bool);
  }

  $.fn.checked = function(bool) {
    return this.setAttr('checked', bool);
  }
I assume I should change all attr to prop?

I think you should add two more helpers (like .val):

.checked() and .disabled() - with no parameters they return a boolean, and with a parameter you can pass in true/false to set the property.

Those two are probably the most commonly used properties and if you had them most people could probably ignore attr vs prop.


The blog entry mentions this, but perhaps without enough detail. Your `.setAttr()` exactly matches the same as the `.attr()` method's new behavior when it's passed a Boolean argument to set. The other two would be great suggestions for 1.7!


I don't think it's clear at all what the purpose of each is, especially if you were coming into jQuery fresh. I would have interpreted .prop as something more like .data.

The doc reads: "The difference between attributes and properties can be important in specific situations. Before jQuery 1.6, the .attr() method sometimes took property values into account when retrieving some attributes, which could cause inconsistent behavior. As of jQuery 1.6, the .prop() method provides a way to explicitly retrieve property values, while .attr() only retrieves attributes.

For example, consider a DOM element defined by the HTML markup <input type="checkbox" checked="checked" />..."

The docs then go into the example on this thread.

Personally, I think that if this is the only specific situation we can think of, it probably wasn't worth introducing a method that parallels attr. As a higher-level library, jQuery ideally will do the right thing without the calling code thinking too hard about exactly what mechanism it's using to do it. (It does this with cross-browser issues, for example.) This was the case already with .attr("checked")...

So if I'm approaching jQuery for the first time, do I use prop or attr, and why?


I really don't like this change. It's just confusing. Since "checked" is an attribute that has to be added to an input elemented for it to be checked, it's still an attribute.

I don't see how prop() is any different than just using data().


I love how fast jQuery is progressing, but it does seem that ultimately the separations of various disciplines (particularly this .attr() and .prop() debate) is a step away from the convenience of jQuery-past.

It's understandable though, because helpers and abstractions add bloat and latency to interactions with the various DOM interfaces. And this latency is the price we have to pay for the benefits these abstractions give us - which include a unified interface to the DOM of many browsers.

The balance of speed vs convenience is very difficult for frameworks like jQuery looking to work for as many people as possible... if you want the convenience at the sacrifice of speed or conversely prefer the speed to the convenience you have one option: build a library specific to your app or your needs.

The rest of us will use jQuery ;)


In the case of attr(), the convenience jQuery was adding was an enormous fudge and attempted to gloss over the fundamental difference between attributes and properties, which has directly led to vast confusion and misunderstanding among developers. It was impossible for even jQuery core developers to explain what attr() was supposed to do. The pre-1.6 attr() was a design mistake that 1.6 is attempting to rectify, which must be a good thing (provided it's been done sensibly).


I love how quickly they're pushing out these releases. It's awesome to have my applications constantly improving in speed without me having to do much.

Although I'm honestly a bit confused on their explanation of .prop and .attr now... Maybe I should just re-read it slower, or give myself a little more time to wake up. Unless someone would care to explain it in simpler terms for me. ;)


Browsers have two concepts for "data that's attached to an element". There are traditional attributes, for example: <input type="text"/> - doing .getAttribute("type") will get you "text".

Additionally there is the concept of DOM object properties - these are properties that exist solely on the JavaScript implementation of the DOM node. For example .selectedIndex is a property that exists on select elements but isn't actually an attribute.

Previously jQuery conflated properties and attributes (sometimes using one, sometimes using another). Unfortunately, while this creates a result that is perhaps slightly more user friendly, it also creates lots of weird edge cases that are hard to define (such as the cases relating to value, outlined in the blog post). For this reason we've split apart the functionality into two realms: .attr()/.removeAttr() and .prop()/.removeProp().

How does this affect you and your applications? It probably (hopefully) won't. Continuing to use .attr()/.removeAttr() will probably be just fine. Using other jQuery helpers, like .val(), will help to cover over the last remaining bits of weirdness that exist.

In short: Nothing much of serious consequence will likely change, but we're going to actively watch the response from this release and make sure we act appropriately, and swiftly, should major problems come up.


> Continuing to use .attr()/.removeAttr() will probably be just fine

Your blog post calls them "breaking changes" for a reason though. Code that does `if ($elem.attr('checked'))` needs to be rewritten to use .prop when upgrading. Saying "It probably (hopefully) won't [affect your applications]" is slightly contradictory.


An informative reply from Mr. Resig himself :) Thanks! I understand now. I generally use .attr to retrieve the id, class, or something like that, which isn't something that usually changes in my scripts. I mainly stick to .val() for inputs, so this definitely clears up my concerns.

I'll go through my code a bit to see if I need to make any changes, but it doesn't seem that way now that it's all more clarified for me.. Besides a couple cases where I check the state of checkboxes. Thanks again for your help, and for jQuery in general. It's made my life/job easier in a completely indescribable way. (I used to be afraid of Javascript.)


That's quite a simplified explanation which sidesteps the issue of properties that correspond to attributes, which is where most of the confusion is going to be. And I totally disagree with your description of things like Boolean attributes/properties as "weird edge cases": their behaviour in most browsers is well-defined, consistent and not really at all weird, particularly if you limit yourself to using properties rather than attributes, which is almost always the correct approach.

Saying that it probably won't affect existing applications is just misleading. 1.6 fundamentally changes the behaviour of attr(), which is a very complicated and commonly used method. Furthermore, there's really no point in this if you're not going to encourage people to move to prop() rather than attr().

The messages coming from jQuery about this change seem very vague to me. If you're going to spring this kind of change on your users then they need to understand what it is that you've changed and why it's a good thing (I think it is, by the way), which one documented example and a hand-wavy assurance that it might probably be mostly OK doesn't do.


Is prop('value') faster than val() now for reading dynamic input?


Probably - but that's mostly due to the fact that .val() does more to ensure that the value being returned is useful (such as turning selected options into arrays, etc.).


Honestly, I think that jQuery pre-1.6 did the right thing almost all the time and we all learned to deal with the boolean attribute edge case just fine. I feel like this change is taking jQuery in the wrong direction. We don't want to look back and say "1.6 is where the bloat began..."


If I understand correctly, .prop reflects the current state of the DOM, .attr reflects the state when loaded or last updated with javascript.

If you have: <input id="test" type="text" value="initial" />

On load, the page should show for $("#test") .prop("value") = "initial", .attr("value") = "initial"

Then, if you type in "current" into the 'test' input box, the page should show: .prop("value") = "current", .attr("value") = "initial" without any other events taking place that would update the value.


Question: When would you ever want the .attr("value")=="initial" in real code? How often is it that you want the original value encoded in the HTML as opposed to the current value of the element as entered by the user?

This is part of why I think .prop vs .attr is a regression. It makes me think twice before I use either--even if this is closer to how the DOM actually behaves, the point of jQuery used to be that it could hide those inane details from me.


The difference between attributes and properties is not an inane detail. It's fundamental, and if you don't understand it then you can't work reliably with the DOM, either with or without jQuery.

Bottom line: use prop().


You could use it to test if the value has been changed.


Thank you! The pure definition of simpler terms I was looking for. Going through my code now to see if I need to make changes!


Note that in the above example, one should really be using .val() instead of .attr('value'), and if so, then nothing will need to be changed.


Seems to have caused using an array to specify easing in jQuery.animate to break. Was a bit surprising.


Do you have more details on this? Can you file a bug report? Thanks!

http://bugs.jquery.com/


it's broken Nivo Slider (2.5.1) but a global replace of '.attr(' with '.prop(' has fixed it. Not sure if this is the best thing to do, but it works


Switched to it and the animations really look smoother now. Sweet release, can't wait for 1.6.1!




Guidelines | FAQ | Support | API | Security | Lists | Bookmarklet | Legal | Apply to YC | Contact

Search: