0

I'm trying to detect keypresses only when a checkbox is checked, however after the first activation of the checkbox it always runs its functions.

Here is "my" code:

var keys = {};
$(":checkbox").click(function() {
    if(this.checked) {
        $(document).keydown(function (e) {
            e.preventDefault()
            keys[e.which] = true;
            printKeys(e);
    });

    $(document).keyup(function (e) {
        e.preventDefault()
        delete keys[e.which];
        printKeys(e);
    });
}

What is inside if(this.checked) will only get executed once the checkbox is checked, but after that it will always detect my key presses regardless of the checkbox being checked or not.

Heretic Monkey
  • 11,687
  • 7
  • 53
  • 122
  • 1
    You're adding an event handler every time you click on a checkbox. That means that if the checkbox is not checked, the event handler remains. If you don't want it to run, remove the event handler when the checkbox is unchecked. Or, listen to the event all of the time, and only do something in the event listener when the checkbox is checked. – Heretic Monkey Mar 05 '19 at 18:23
  • Possible duplicate of [Checkbox Check Event Listener](https://stackoverflow.com/questions/14544104/checkbox-check-event-listener) – Heretic Monkey Mar 05 '19 at 18:26

1 Answers1

0

Please read the edit as this soluton is not very optimal

Thanks to Heretic Monkey I found a workaround, I just need to add an else statement that turns off the $(document) event handlers once the checkbox is unchecked, like so:

var keys = {};
$(":checkbox").click(function() {
    if(this.checked) {
      $(document).keydown(function (e) {
        e.preventDefault()
        keys[e.which] = true;
        printKeys(e);
      });

      $(document).keyup(function (e) {
        e.preventDefault()
        delete keys[e.which];
        printKeys(e);
      });
    } else {
      $(document).off();
    }
});

I don't know if this is the most optimal solution, but it works.

Important Edit

As comments pointed out it is not recommendable to turn off an event handler that might require to be executed later on, another workaround is by always listen for the keypress but only run the function if the checkbox is checked like so:

$(document).keydown(function (e) {
  console.log($(":checkbox").is(":checked"));
  if($(":checkbox").is(":checked")) {
    e.preventDefault();
    keys[e.which] = true;
    printKeys(e);
  }
});

$(document).keyup(function (e) {
  if($(":checkbox").is(":checked")) {
    e.preventDefault();
    delete keys[e.which];
    printKeys(e);
  }
});
Community
  • 1
  • 1
  • 1
    I really don't recommend turning on and off events. As soon as you introduce any other events, your `off()` will stop all other event handlers and it will be hard to determine why. – Erik Philips Mar 05 '19 at 19:02
  • 2
    If you read the remainder of my comment, or the possible duplicate, you'll find that it's probably better to always listen for `keydown`, and only do something if the checkbox is checked. – Heretic Monkey Mar 05 '19 at 19:06
  • I'm sorry, maybe I shouldn't have been so hasty looking for an answer and answering myself too, either way the way you propose of always listening to the event but only executing it once the checkbox is checked works too, I guess I'll go with that approach. – Arpad Flandorffer Mar 05 '19 at 19:22