We all love jquery, not only because it has made working with DOM easier but also because it is such a forgiving framework, tries to guess your intentions and return you what you intended and not necessarily what you asked for. Well, we will see how this could affect the risk of upgrading to jquery 1.6+ (currently at 1.7). But to be honest out of all libraries, jquery was the one I would least to expect a breaking change - it is a library that hides breaking differences of browsers so knows the pain of a breaking change!
According to jquery release note, upgrading to jquery 1.6.1 should not require any change:
With the introduction of the newOK, I am relieved! So I can happily upgrade our jquery 1.5 to 1.6.1 (and even better 1.7). Is it really safe? Well, the answer depends on how you have used (or abused) the method attr() on previous versions..prop()
method and the changes to the.attr()
method, jQuery 1.6 sparked a discussion about the difference between attributes and properties and how they relate to each other. It also came with some backwards compatibility issues that have been fixed in 1.6.1. When updating from 1.5.2 to 1.6.1, you should not have to change any code.
attr() vs. prop()
All the difference between v 1.5 vs. 1.6 boils down to introduction of prop() and change of the semantics of the existing attr() that can break your code, well it did ours - unfortunately I believe due to our bad jquery code. prop() will represent the semantic of the property which could have been stored as an attribute while the attr() will return literal (string) value of the attribute.
Confused? Well, I believe origin of the confusion was the poor HTML attribute definition - let's blame W3C here, they always get blamed anyway! To explain it further, if I have a checkbox that is checked, its "checked" property will be true but its "checked" attribute will be "checked".
In code terms, let's imagine this scenario:
<button name="chip" id="chap" disabled="disabled">happy chappy</button>
<input type="checkbox" id="chk" checked="checked">Hello</input>
As you can see we have to elements, a checked checkbox and a disabled button.
This is how this is going to look in jquery 1.5 (jsfiddle line here)
console.log("disabled attr: ", $("#chap").attr("disabled")); //outputs "disabled attr: true"
console.log("checked attr: " + $("#chk").attr("checked")); //outputs "checked attr: true"
This is how this is going to look in jquery 1.6 (jsfiddle link here)
console.log("diabled attr:", $("#chap").attr("disabled")); // disabled attr: disabled
console.log("checked attr: " + $("#chk").attr("checked")); // checked attr: checked
console.log("diabled prop: ", $("#chap").prop("disabled")); // diabled prop: true
console.log("checked prop: " + $("#chk").prop("checked")); // checked prop: true
console.log("checked attr: " + $("#chk").attr("checked")); // checked attr: checked
console.log("diabled prop: ", $("#chap").prop("disabled")); // diabled prop: true
console.log("checked prop: " + $("#chk").prop("checked")); // checked prop: true
Will attr() always return the literal value of the attribute? No, and that is what confuses me but again I think it is partly due to inconsistencies of HTML attributes. For example, value of the disabled attribute does not have to be "disabled" to be effective, its mere existence signifies "disabledness" of the element. For example, if the attribute has no value, element is still disabled (or checked) and attr() will return element's implied value and not the literal one (which I believe should not be so and attr() should just stick to the literal value):
<button name="chip" id="chap" disabled>happy chappy</button>
<input type="checkbox" id="chk" checked>Hello</input>
<input type="checkbox" id="chk" checked>Hello</input>
console.log("diabled attr:", $("#chap").attr("disabled")); // disabled attr: disabled
console.log("checked attr: " + $("#chk").attr("checked")); // checked attr: checked
console.log("checked attr: " + $("#chk").attr("checked")); // checked attr: checked
We experienced two types of problems:
- Calling $("#chap").attr("disabled", "") will totally remove the attribute (enable the element) in jquery 1.5, while in jquery 1.6 it will just set the value to empty string. So my colleagues have been conveniently using attr("disabled", "") to enable the element while they should have just used removeAttr() which has been there since v1.0. Semantically, attr("disabled", "") should set the attribute to empty string but jquery used to gracefully interpret that as the same as setting property to false - not anymore.
- If you use the literal value of the attr() since it would return false/true but now it will return "disabled"/undefined. In our case the value was being passed to the server, hence server was expecting a boolean (false/true) and it broke when it saw "disabled"/undefined!
Conclusion
Upgrading your code from jquery 1.5 to 1.6 can break your code around the attr() function. So be careful and plan a full regression testing after the upgrade.
No comments:
Post a Comment