Javascript onkeydown event fire only once?

32,085

Solution 1

You could set a flag:

var fired = false;

element.onkeydown = function() {
    if(!fired) {
        fired = true;
        // do something
    }
};

element.onkeyup = function() {
    fired = false;
};

Or unbind and rebind the event handler (might be better):

function keyHandler() {
     this.onkeydown = null;
     // do something
}

element.onkeydown = keyHandler;

element.onkeyup = function() {
    this.onkeydown = keyHandler;
};

More information about "traditional" event handling.

You might also want to use addEventListener and attachEvent to bind the event handlers. For more information about that, have a look at quirksmode.org - Advanced event registration models.

Solution 2

I'm surprised it's not mentioned, there's also event.repeat:

document.addEventListener('keydown', (e) => {
  if (e.repeat) return;

  console.log(e.key);
});

This will only fire once per each keypress, since event.repeat turns true after holding the key down.

https://developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent/key#keyboardevent_sequence

Solution 3

There's a "once" parameter you can use

https://developer.mozilla.org/en-US/docs/Web/API/EventTarget/addEventListener

Eg:

element.addEventListener('keydown', function(event) {  
    doSomething()
}, {once: true});

It'll remove it as soon as it's been called.

Alternatively you can use removeEventListener if it's a named function

Solution 4

Here you go:

test.onkeydown = function() {
    if ( this.className === 'hold' ) { return false; }
    this.className = 'hold';

    // call your function here
};

test.onkeyup = function() {
    this.className = '';
};

Live demo: http://jsfiddle.net/simevidas/xAReL/2/

Solution 5

Here is a method that uses addEventListener and removeEventListener

var textBox = document.getElementById("textBox");
function oneKeyDown(){
    $("body").append("<h1>KeyDown<h1>"); //just to show the keypress
    textBox.removeEventListener('keydown', oneKeyDown, false);
}
function bindKeyDown(){
  textBox.addEventListener('keydown', oneKeyDown, false);
}
textBox.addEventListener('keyup', bindKeyDown, false)   
bindKeyDown();

Code example on jsfiddle.

One note, for IE you will need to use attachEvent, detachEvent.

Share:
32,085
WindowsMaker
Author by

WindowsMaker

Updated on September 18, 2021

Comments

  • WindowsMaker
    WindowsMaker over 2 years

    I want to have a onkeydown event fire a function only once. for that function to fire again, the user has to release the key and press/hold again. I know its fairly simple but I'm new at JS. Also I prefer to avoid using jQuery or other libs. One more thing, this should work for both ie and firefox.

  • Felix Kling
    Felix Kling about 13 years
    i prefer to avoid using jquery or other libs. And one itself does not help. You'd have to rebind the event handler again.
  • Felix Kling
    Felix Kling about 13 years
    You should note that this only works in Webkit and Firefox. IE uses attachEvent.
  • Mark Coleman
    Mark Coleman about 13 years
    Got distracted and forgot to mention it. Thanks for the reminder.
  • Sebastian Budka
    Sebastian Budka about 2 years
    It's probably worse performance wise, but i like this answer much more than accepted one, at least in my small applications.