Change event not firing when radio button is selected with keyboard
<script>
$("input[name='my_radio_button']").change(function(){
if ($("input[@name='my_radio_button']:checked").val() == 'ONE'){
do_this_stuff();
} else { do_other_stuff(); }
});
</script>
<input type="radio" name="my_radio_button1" id="radio1" value="ONE" checked />
<input type="radio" name="my_radio_button2" id="radio2" value="TWO" />
(assume complete HTML and the script firing when all is ready)
The change event seems to fire w开发者_StackOverflowhen clicking to select a radio option, but not when the selection is changed with keyboard. Can anything be done about this?
edit - makes no difference if I use bind
or live
-- is this just a bug?
To clarify, the event does not fire even after focus is lost.
edit 2 - nobody knows the reason for this?
edit 3 - as DonaldIsFreak pointed out this seems to be a chrome problem
Here is a reliable fix http://evilstreak.co.uk/blog/fixing-change-events-on-radios
And using it this is how you would implement it with your example: And here is a demo of the code below http://www.jsfiddle.net/uDkdJ/1/ I tested this demo in FF3.6, IE8, Safari5, Chrome7, and Opera10.65
$.fn.fix_radios = function() {
function focus() {
if ( !this.checked ) return;
if ( !this.was_checked ) {
$( this ).change();
}
}
function change( e ) {
if ( this.was_checked ) {
e.stopImmediatePropagation();
return;
}
$( "input[name=" + this.name + "]" ).each( function() {
this.was_checked = this.checked;
} );
}
return this.focus( focus ).change( change );
}
$(function() {
$( "input[type=radio]" ).fix_radios();
$("input[name='my_radio_button']").change(function(){
if ($("input[@name='my_radio_button']:checked").val() == 'ONE'){
do_this_stuff();
} else { do_other_stuff(); }
});
});
In jquery 1.4.2 @ selector does not work. Look at this example to see if it is useful to you, change the "change" event per "click".
html
<input type="radio" name="rdio" value="a" checked="checked" />
<input type="radio" name="rdio" value="b" />
<input type="radio" name="rdio" value="c" />
<br />
<div id="test"></div>
javascript:
$("input[name='rdio']").click(function(){
if ($("input[name='rdio']:checked").val() == 'a')
$("#test").append("<div>a</div>");
else if ($("input[name='rdio']:checked").val() == 'b')
$("#test").append("<div>b</div>");
else
$("#test").append("<div>c</div>");
});
example
ref 1
ref 2
Unfortunately, radio buttons don't fire change events when changed with the keyboard, until you lose focus.
If you want to work around this problem, you can always set up a timer that monitors the state, and dispatches an event when it changes. Something like (pseudocode):
var monitorRadio = function(radio)
{
var state = $("input[@name='']:checked").val();
$(radio).data("state", state);
var func = function()
{
var state = $("input[@name='']:checked").val();
if (state != $(radio).data("state"))
{
$(radio).data("state", state);
// dispatch the change event
$(radio).change();
}
setTimeout(100, func());
};
func();
}
I'm not having much luck getting the radio button to change it's state with the arrow keys in my jsfiddle, so here's a blind answer:
Use .keypress()
The same rule about not changing until loosing focus applies to select boxes, and I've successfully used .keypress()
there
http://api.jquery.com/keypress/
$("input[name='my_radio_button']").bind('change keypress', function(){
if ($("input[@name='my_radio_button']:checked").val() == 'ONE'){
do_this_stuff();
} else { do_other_stuff(); }
});
The problem with this method is that the event will fire once when the user presses a key, and again when it loses focus. I'm not sure what do_this_stuff()
and do_other_stuff()
do, but if them firing more than once is a problem, you could fix this with a var to check what the previous value was, so you know if it's actually changed:
$("input[name='my_radio_button']").bind('change keypress', function(){
if ($(this).value() != prevValue) {
if ($("input[@name='my_radio_button']:checked").val() == 'ONE'){
do_this_stuff();
} else { do_other_stuff(); }
}
prevValue = $(this).value();
});
精彩评论