4

I can reduce the behavior to a simplest case (tested in the latest Chrome, Safari, Firefox, IE 9 and 10 (jsfiddle doesn't work on IE 8)):

http://jsfiddle.net/fjvqa/1

$("input").click(function (evt) {
    console.log("click event handler invoked", evt);
    console.log($("input").attr("checked"));
    console.log($("input").prop("checked"));
    console.log($("input").is(":checked"));
});

$("input").click();

with the HTML:

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

The output is:

undefined
false
false

so is it supposed to be correct that it should report the checkbox is not checked?

If it is correct, then why in jQuery 1.9.1, the behavior is completely the opposite? http://jsfiddle.net/fjvqa/2

If it isn't correct, I wonder why such a simple bug would be there still in jQuery 1.8.3, which was released Nov 13, 2012, which is just about 4 months ago... for such an obvious bug?

P.S. I do understand that (1) the attr() should not be used but prop() should be used instead. I print it out just to see what's happening. (2) the change handler actually will report the opposite of what click reports if using jQuery 1.8.3: http://jsfiddle.net/fjvqa/3 if it is jQuery 1.9.1, they report the same thing: http://jsfiddle.net/fjvqa/4 What I am looking for is what is the real situation of what is supposed to happen.

Brian Tompsett - 汤莱恩
  • 5,753
  • 72
  • 57
  • 129
nonopolarity
  • 146,324
  • 131
  • 460
  • 740
  • What's interesting is that in the browser, the checkbox does appear to become checked. I tried changing the call of `click` to `trigger('click')` and it made no difference. I'm sure there's some reason explained in the docs but I'm not sure at the moment – helion3 Apr 03 '13 at 04:43
  • Have you seen this previous topic could be helpful! [http://stackoverflow.com/questions/15070277/why-jquery-1-9-attr-method-not-deprecated][1] [1]: http://stackoverflow.com/questions/15070277/why-jquery-1-9-attr-method-not-deprecated – Sam Deering Apr 03 '13 at 04:51
  • Also you could use this as well: console.log($("input:checked").length > 0); – Sam Deering Apr 03 '13 at 04:53
  • 2
    I think this was changed in this bugfix: http://bugs.jquery.com/ticket/3827. They probably didn't want to make an incompatible change in a minor release, so it's only in 1.9.x. – Barmar Apr 03 '13 at 04:58
  • 1
    If you want to accurately get the checkbox state, bind to the `change` event instead of the `click` event. Eg. `$("input").change(function(evt) { ... });` Example: http://jsfiddle.net/amyamy86/fjvqa/13/ – Amy Apr 03 '13 at 05:32
  • Yes, I believe "click" is pre-"state change", so it would indeed report false. The change event is triggered after the state of the checkbox is changed and should report the accurate value of the checked property. – Andrew Senner Apr 11 '13 at 18:49

1 Answers1

1

Comments have given you the answer - the change happens AFTER the click. You're binding to an event that makes the change happen. I would guess you're seeing the discrepencies between the versions because there is no clear definition on this. The solution is to use .change instead of .click:

Updated Fiddle:
http://jsfiddle.net/fjvqa/22/

$("input").change(function (evt) {
    console.log("click event handler invoked", evt);
    console.log($("input").attr("checked"));
    console.log($("input").prop("checked"));
    console.log($("input").is(":checked"));
});

$("input").click();

Outputs:

checked
true
true
Thom Porter
  • 2,604
  • 2
  • 19
  • 23
  • but so can it be considered "fixed" in jQuery 1.9.1. This jsfiddle is using 1.9.1 (not 1.8.3) and it works: http://jsfiddle.net/fjvqa/23/ – nonopolarity Apr 17 '13 at 13:31
  • You might consider that fixed, but who's to say it won't break again in the future... Binding to `.change()` ensures that changes to how `.click()` works won't affect our code... – Thom Porter Apr 17 '13 at 21:37