Skip to content Skip to sidebar Skip to footer

How To Prevent Triggering Button Event When Press 'enter' Key And Hold?

Case are show blow: If you click the button and then press 'enter' key and hold for it, the button's click event will trigger constantly. There's no jQuery, no form, no input. I w

Solution 1:

It happens because pressing Enter on a button triggers its click event, and when you hold a key, key repeat kicks in and keeps "typing" that key over and over.

If you want to ignore the event for a period of time after it's been triggered once, you can add code to your handler to do that:

var IGNORE_TIME = 1000; // One second
var lastClick = null;
document.querySelector('button').addEventListener('click', function (e) {
  var now = Date.now();
  if (!lastClick || now - lastClick > IGNORE_TIME) {
    lastClick = now;
    console.log(1);
  }
});
<button>press Enter</button>

If you never want pressing Enter on the button to "click" it (which I don't recommend, you may make it difficult for someone with a disability who relies on using the keyboard), you can prevent the keydown event on the button:

document.querySelector('button').addEventListener('click', function (e) {
  console.log(1);
});
document.querySelector('button').addEventListener('keydown', function (e) {
  var key = e.keyCode || e.charCode;
  if (key == 13) {
    e.stopPropagation();
    e.preventDefault();
  }
});
<button>press Enter</button>

See also vlaz's answer, which only prevents the keypress if it's from key repeat, which seems like an excellent compromise.


Solution 2:

This is due to the fact that when you click the button. the button keep the focus state


Solution 3:

Revised answer: When a key is held down, the sequence of events you would expect to get is keydown -> keypress -> keydown -> keypress -> (... same two events repeated ...) -> keyup. Knowing that, you can keep track of what was pressed in keydown and know that it finally ended in a keyup.

document.querySelector('button').addEventListener('click', function (e) {
  console.log(1);
});

var keysCurrentlyPressed = {};

document.querySelector('button').addEventListener('keydown', function (e) {
  var key = e.keyCode || e.charCode;
  if (keysCurrentlyPressed[key]) {
    e.stopPropagation();
    e.preventDefault();
  } else { //this is the first time the key is pressed, add an entry for this key
    keysCurrentlyPressed[key] = true;
  }
});

document.querySelector('button').addEventListener('keyup', function (e) {
  var key = e.keyCode || e.charCode;
  delete keysCurrentlyPressed[key]; //note that the key isn't pressed any more
});
<button>press Enter</button>

This will work on any environment that is DOM Level 3 compliant, so all major browsers. However, according to MDN some older environments would treat a key pressed down as repeatedly pressing the key, sending keydown -> keypress -> keyup each time. If that's the case, you can use T.J. Crowder's solution which uses a timeout period.

If using ES6, you can store the pressed keys in a Set and you can wrap the whole thing in a closure, to prevent the keys from being available to other code that probably doesn't need them.

document.querySelector('button').addEventListener('click', function (e) {
  console.log(1);
});

(function() {
  const keysCurrentlyPressed = new Set();

  document.querySelector('button').addEventListener('keydown', e => {
    const key = e.keyCode || e.charCode;
    if (keysCurrentlyPressed.has(key)) {
      e.stopPropagation();
      e.preventDefault();
    } else {
      keysCurrentlyPressed.add(key);
    }
  });

  document.querySelector('button').addEventListener('keyup', e => keysCurrentlyPressed.delete(e.keyCode || e.charCode));

})()
<button>press Enter</button>

Original answer: You can prevent a key being held down by looking at the Event.repeat property. However, the repeat property is not supported on Edge or Internet Explorer, so this will only work on Chrome, Firefox and Safari.

document.querySelector('button').addEventListener('click', function (e) {
  console.log(1);
});

document.querySelector('button').addEventListener('keydown', function (e) {
  if (e.repeat) { //don't do anything if a key is held down.
    e.stopPropagation();
    e.preventDefault();
  }
});
<button>press Enter</button>

If you clock the button and hold down Enter or even Space, you won't get repeated events.

Worth noting - you need to add a listener for a keyboard event (keydown, keypress, or keyup) to use the repeat property. The click is a mouse event which doesn't have a repeat, as it makes no sense for it.


Solution 4:

As the button has focus, every event (as is pressing Enter) is directed to that button and executed. To prevent it from happening multiple times, you can remove the focus by using blur(). It then executes only once, untill the user sets focus on the button again.

document.querySelector('button').addEventListener('click', 
  function (e) {
    console.log(1);
    this.blur();
})

Post a Comment for "How To Prevent Triggering Button Event When Press 'enter' Key And Hold?"