Can anyone explain why the code fragment does not work after pressing toggle 3 times?
The attribute checked is still set to "checked" but the browser doesn't check the checkbox anymore.
$(document).ready(function() {
$("#btn").click(function() {
if($("#chk").is(":checked"))
$("#chk").removeAttr("checked");
else
$("#chk").attr("checked","checked");
$("#lbldebug").text($("#chk").clone().wrap('<p>').parent().html());
});
});
See http://jsbin.com/ewawih/2/edit
I've tested it both on Opera and Chrome, with the same problem in both.
What am I missing here?
for jQuery 1.9+, attr for properties will not work, you can simplify a toggle of a checkbox like:
$("#btn").click(function() {
$("#chk").prop("checked",!$("#chk").prop("checked"));
$("#lbldebug").text($("#chk").clone().wrap('<p>').parent().html());
});
EDIT: see that:!$("#chk").prop("checked")
notice that first character which makes the boolean value the opposite of what it currently is, thus the toggle works by setting it to the opposite of what it currently is, no matter what that value is.
Just for an explanation, accessing the attr('checked')
in jQuery 1.9+ gets the original attribute - which is a part of the markup, while the .prop("checked")
accesses the current property value for that. Some things are still attributes, however this is one that is a property and access to properties through/as an attribute was deprecated and then removed in jQuery 1.9/2.0. In jQuery 1.6 they made changes and in 1.6.1 they reverted some of those changes and deprecated the attr()
even though it still worked due to those 1.6.1 change. 1.9+ then removed those usages. Think of an attribute as some string, and a property as a current value. Your use of the the attribute was accessing that string which did not change whereas the property did change and hence why .prop()
works.
Also note that your use of the text/wrap for the element (for debug I assume) does not show the property but only the "string" of the element which does not include the property - hence it appears not to change/be there in your "debug" this way and your would need to add access to the property (a true/false value) and append that also to get a visible representation of that value.
For 1.9.1 on chrome:
$("#chk").checked //returns undefined
(used to work prior to change, feels like a bug)
EDIT2:wrong:incorrect form
$("#chk")[0].checked // proper form works
$("#chk").get(0).checked // same as above, works
document.getElementById("chk").getAttribute("checked") // returns "checked" or null or "true" or "fun" or empty "" if it was set thay way, attribute present checks box
$("#chk").is(":checked") // returns true/false current value
$("#chk").attr("checked") // returns "checked" or undefined does not change
document.getElementById("chk").defaultChecked // returns true/false of original, does not change
$("#chk").prop("checked") // returns current value true/false
document.getElementById("chk").checked //returns current value true/false
$("#chk").is("[checked]") // attribute selector returns original value, does not change
if($("#chk").is(":checked"))
$("#chk").prop("checked", false);
else
$("#chk").prop("checked", true);
You should use .prop()
and also checked can also be specified with BOOLEAN.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With