#3827 closed bug (fixed)
Checkbox state inconsistent in click event handler
Reported by: | skorpan | Owned by: | dmethvin |
---|---|---|---|
Priority: | high | Milestone: | 1.9 |
Component: | event | Version: | 1.2.6 |
Keywords: | 1.9-discuss | Cc: | |
Blocked by: | Blocking: |
Description
I'm not sure whether this is intended behavior or simply impossible to hack in pure JavaScript, but here goes nothing...
There is a significant difference between actually clicking an element and the triggering of the click event handlers bound to that element by JQuery. Attached to this ticket is a test script and its HTML to reproduce this "bug". What happens is:
- I click the checkbox and see "State: ON" in the Firebug console. I click it a few times to verify that the correct state is always reported.
- I click the button which in turn programmatically triggers the click event bound to the checkbox. Now the INCORRECT state is reported every time. This is probably due to the bound event handler being triggered before any internal behavior.
Attachments (3)
Change History (36)
Changed 15 years ago by
Changed 15 years ago by
comment:1 Changed 15 years ago by
comment:2 Changed 15 years ago by
I did some further work on this, and I agree with your analysis. Test case attached, checked in FF3 and IE8B2. The difference is because .trigger("click") calls the handler before the checkbox native click() method. A click on the checkbox calls the checkbox native click() method; that method causes the onclick event to fire and jQuery calls the handler.
See this thread for more discussion:
http://groups.google.com/group/jquery-dev/browse_frm/thread/39c3dabc8ac3569a
Changed 15 years ago by
Attachment: | test-3827.html added |
---|
event handling with jQuery trigger() and DOM events
comment:3 Changed 14 years ago by
Owner: | brandon deleted |
---|
comment:4 Changed 14 years ago by
Closed duplicate #5727 with another test case.
More info:
http://www.w3.org/TR/DOM-Level-2-HTML/html.html#ID-6043025
Note: During the handling of a click event on an input element with a type attribute that has the value "radio" or "checkbox", some implementations may change the value of this property before the event is being dispatched in the document. If the default action of the event is canceled, the value of the property may be changed back to its original value. This means that the value of this property during the handling of click events is implementation dependent.
It seems like most modern browsers change the checkbox state before calling the event handler, then revert it if the default action is cancelled.
comment:5 Changed 13 years ago by
Summary: | Click event triggered "too late" → Checkbox state inconsistent in click event handler |
---|
Closed duplicate #6775.
comment:6 Changed 13 years ago by
Resolution: | → wontfix |
---|---|
Status: | new → closed |
This behavior has been consistent since jQuery's first version, so there's no way we could change it without breaking significant existing code.
comment:8 Changed 13 years ago by
If you compare jQuery's behaviour with raw JavaScript the results are opposite.
The best policy here is to fix this in the next major version of jQuery and tell people there's a BC break otherwise everyone will have to put up with annoying workarounds until the end of time.
comment:9 Changed 13 years ago by
Hey,
I was having the same issue, and found a great answer on Stack Overflow here: http://stackoverflow.com/questions/3478267/jquery-strange-behaviour-on-click-from-a-click
Basically, instead of just calling the click() method of the checkbox, you set the attribute "checked" to true or false, which checks or unchecks the box, and then manually call the event handler by using triggerHandler("click"). Here's the code that I used:
Check the box: $(this).find("input.city_selector_chk").attr('checked', 'true'); $(this).find("input.city_selector_chk").triggerHandler("click");
Uncheck the box: $(this).find("input.city_selector_chk").attr('checked', ); $(this).find("input.city_selector_chk").triggerHandler("click");
Hope this helps! Paul
comment:12 Changed 12 years ago by
I don't understand why this is a won't fix. Manual triggering of event is basically broken with this bug!
comment:13 Changed 12 years ago by
Having recently discovered this issue I note that there is different behaviour between different versions of jQuery;
Given a input:checkbox that has both an inline onclick handler and a jQuery bound click handler the value of checked differs according both to how the click is triggered and what version of jQuery is in use.
Actually clicking on the element in the browser changes the checked value before the events are handled.
With jQuery 1.6.2 using $(element).trigger('click') handles the events before the checked value changes.
In jQuery 1.3.2 the behaviour is slightly different as one handler is called before the checked state changes and the other after.
So at least now the behaviour is consistent across handlers and predictable, though I think ought still be fixed. If not in a minor version change then certainly by jQuery 2.0
comment:21 Changed 11 years ago by
As a note to anyone else suffering with this bug, you can work around this problem by wrapping your checkbox's click event handler in setTimeout(function(){ ... }, 1);
comment:23 Changed 11 years ago by
Keywords: | 1.9-discuss added; click event trigger checkbox button removed |
---|
comment:24 Changed 11 years ago by
I too am having issues with this. I dynamically add a new checkbox, and using delegated 'click' handler:
$('div.parent').on('click', 'input[type=checkbox].classname', function() {
if ($(this).is(':checked')) { <--- this shows opposite value when doing $(element).trigger('click');
do stuff
}
});
comment:25 Changed 11 years ago by
Just 2 cents.
Ideally jQuery click() and DOM click() should work identically for elements which have DOM click().
comment:26 Changed 11 years ago by
There have been 13 duplicate bugs posted in the past 3 years indicating many people find it should not be the way it is. Several fixes ranging from setTimeout(..., 1) to setting the checked attribute and calling the triggerHandler have been proposed but these are work arounds to account for a bug, i.e. people aren't accepting this as expected behavior. Checat makes a valid point for why expectations supports the idea that this is a bug. The cause of the problem has been pointed out by dmethvin and it honestly sounds like an easy fix.
Fixing this bug in a new release would only impact those who have legacy code referencing a constantly changing 'newest release'. Those developers should know that a constantly updated library will occasionally not only have changes, but fixes, that would impact their projects.
comment:28 Changed 11 years ago by
Milestone: | 1.3 → 1.9 |
---|---|
Priority: | minor → high |
Okay, let's try one last time, because this one bothers me too. I think this can be fixed with the 1.7 special event hooks if we assume that click
is a DOM event and don't let it flow through the normal jQuery.event.trigger
path. This may have negative effects for non-DOM usages however, so it's a question of what breaks when we fix this. See also #12379.
comment:30 Changed 11 years ago by
Resolution: | wontfix |
---|---|
Status: | closed → reopened |
comment:31 Changed 11 years ago by
Owner: | set to dmethvin |
---|---|
Status: | reopened → assigned |
comment:32 Changed 11 years ago by
Resolution: | → fixed |
---|---|
Status: | assigned → closed |
Fix #3827. Get the correct checkbox status for a click handler.
Changeset: 1fb2f92c357b985a5ba18d0938edd27b5f64d8c3
Can you explain what behavior you expected? Does it differ from raw Javascript behavior in some undesirable way? In general, all the handlers have to run before the browser's default action is taken. That's because the event handler can return false or e.preventDefault() to stop the default action.