2

I have a small snippet of code which I use to toggle the checked property of a checkbox when the space bar is pressed.

$(document).on('keydown', function(e) {
  if (e.which === 32) {
    e.preventDefault();
    $('#example').prop('checked', function() {
      return !this.checked;
    });
  }
});

The above works fine in Chrome v30 and IE10, but not in Firefox v24. The problem occurs when you click the checkbox, and then use the space bar to toggle it, it momentarily checks it, and then unchecks it, and vice versa.

I believe the problem has something to do with the fact that the click event is triggered in Firefox when using keydown(), despite using e.preventDefault() (which prevents the click event from triggering in both Chrome and IE).

I tried using the same code, binding the keyup event. This fixed the problem in Firefox, but then introduced the same problem to IE.

Here's the fiddle where Firefox is affected

Does anybody know why this is happening, and how I can get around it?

Community
  • 1
  • 1
billyonecan
  • 20,090
  • 8
  • 42
  • 64

2 Answers2

2

I think it's normal behaviour. You are hitting two different events (the checkbox change, and the keydown on document), so we cannot expect .preventDefault() to work.

I'd simply add a condition for that:

if (e.target != $('#example').get(0)) {
    if (e.which === 32) {
        $('#example').prop('checked', ! $('#example').is(":checked"));
    }
}

We check that the "space" event is not triggered by the checkbox itself.

Updated fiddle: http://jsfiddle.net/3pmvw/23/

jjmontes
  • 24,679
  • 4
  • 39
  • 51
  • One more thing, like @davidkonrad example, you don't need that function closure for the property. Updated example: http://jsfiddle.net/3pmvw/50/ (if you are ok, I'll update the solution above to make it more correct). – jjmontes Oct 30 '13 at 13:17
  • i did it that way so that I didn't have to call `#example` from the dom a second time, not that it would make much difference – billyonecan Oct 30 '13 at 13:46
  • I still don't fully understand why `preventDefault()` doesn't prevent the click event from firing in Firefox when the element has focus. Maybe it has something to do with the order in which events are dispatched, as `keyup()` does prevent it in Firefox, but not IE – billyonecan Oct 30 '13 at 13:48
  • I'm not 100% sure, but the thing is that for checkboxes the browser fires an event internally (click), which is different and not in the same event chain as your `keydown`. No idea about ordering in different browsers :?. See if this answer helps: http://stackoverflow.com/questions/11205957/jquery-difference-between-change-and-click-event-of-checkbox – jjmontes Oct 31 '13 at 18:00
0
jQuery(document).keydown(function (e) {
        event = e || window.event;
        event.stopImmediatePropagation();

        if (event.keyCode == 32) {
            if (jQuery("#indian_holder").is(":checked")) {
                jQuery("#indian_holder").prop("checked", false);
            }
            else {
                jQuery("#indian_holder").prop("checked", true);
            }
        }
    }); 

This is perfectly work for me.