Welcome to the Treehouse Community

Want to collaborate on code errors? Have bugs you need feedback on? Looking for an extra set of eyes on your latest project? Get support with fellow developers, designers, and programmers of all backgrounds and skill levels here with the Treehouse Community! While you're at it, check out some resources Treehouse students have shared here.

Looking to learn something new?

Treehouse offers a seven day free trial for new students. Get access to thousands of hours of content and join thousands of Treehouse students and alumni in the community today.

Start your free trial

JavaScript

How to prevent .keydown from firing endlessly when key is pressed and held?

Title pretty much says it all. I am using .keydown to trigger a function. The problem is I need it to only run once but if you hold down the key .keydown will fire endlessly.

Here is my code...

$(document).ready(function() {

    $("#images")
        .css("background-image", "url(images/ready.gif)")
        .css('cursor','pointer')
        .mousedown(function(){
            $(this).css("background-image", "url(images/cool.gif)");
        })
        .mouseup(function(){
            $(this).css("background-image", "url(images/ready.gif)");
        });

    $(document)
        .keydown(function(e){
            if(e.which == 32){
                playBall();
                $("#images")
                    .css("background-image", "url(images/throw.png)");
                $("#ball")
                    .finish()
                    .show()
                    .animate({'left':'835px'},500,function(){
                        $(this).hide();
                        $(this).css('left', '520px')
                    });
            }
        })
        .keyup(function(e){
            if(e.which == 32){
                $("#images")
                    .css("background-image", "url(images/ready.gif)");
                $("#ball")
                    .hide();
            }
        });
});

Maybe you create a variable var i = 0 outside the keydown function,

inside the keydown function you put: if(e.which == 32 && i ==0){ i++; ... }

I think that you so can prevent keydown from firing endlessly. because in one point the variable i would be one and the if statement would not pass

and on the end inside keyup you can reset the variable i, only set it to 0 .keyup(function(e){ if(e.which == 32){ i =0; ... }

1 Answer

I would create a flag or boolean variable called isKeyDown and set it to true when the key is down and false when the key is up. Then, in your keydown function, you can use an if conditional where if true, then skip otherwise run the function and set the value to true. On keyup, set the value to false.

Example:

var isKeyDown = false;
$(document).keydown(function() {
    if (!isKeyDown) {
        //do something
        isKeyDown = true;
    }
});

$(document).keyup(function() {
    isKeyDown = false;
});

Some developers also recommend binding and unbinding the event, but I believe you would need to set the keyup and keydown event functions to a variable. Someone with more experience can correct me on this.

I was thinking something like that might work and I did try it but I probably didnt do it right.

Im thinking maybe Ill setup a dummy file just to work on this section. See if I can get it to work using this checking for a variable technique.

Rhett, here is a basic version of the same problem using pure javascript. Note that I am using the not operator "!" in the if conditional to say if isKeyDown is not down, then run the statements inside the if block. Otherwise, do nothing (an implied else). On the onkeyup, we set the flag back to false.

var isKeyDown = false;

document.onkeydown = function() {
  if (!isKeyDown) {
    console.log("Down");
    isKeyDown = true;
  }
}

document.onkeyup = function() {
  console.log("Up");
  isKeyDown = false;
}