Search code examples
javascripthtmlloopsonkeydownonkeypress

Loop a function while key is pressed


I'm trying to move a div up and down using two keys in Javascript. The idea is that while a certain key is depressed, a function loops and adds to the div's 'top' style value each time. The basic function works, but I can't get it to loop and I can't get anything to respond to a keypress.

It's hard to find info on keypress handling in Javascript, it seems most people use jQuery to handle that.

Is my use of the do-while loop correct? is there a better way to handle keydown and keyup events?

Here's my code:

var x = 0;
console.log(x);

function player1MoveDown() {
            var value = document.getElementById("player1").style.top;
            value = value.replace("%", "");
            value = parseInt(value);
            value = value + 1;
            value = value + "%";
            document.getElementById("player1").style.top = value;
            console.log(value);
        }    //moves paddle down; adds to paddle's 'top' style value

function player1MoveSetting() {
    x = 1;
    do {
        setInterval(player1MoveDown(), 3000);
    }   
    while (x == 1);
    console.log(x);
} //paddle moves while x=1; runs player1MoveDown function every 3 seconds

 function player1Stop() {
    x = 0;
 }

And here's the relevant bit of HTML:

<div class="paddle" id="player1" style="top:1%" onkeydown="player1MoveSetting()" onkeyup="player1Stop()"></div>


Solution

  • You cannot attach a keydown event to a div, unless it has a tabindex:

    <div class="paddle" id="player1" 
         onkeydown="player1MoveSetting()"
         onkeyup="player1Stop()"
         tabindex="1"
    >
    </div>
    


    You can replace all this code:

    var value = document.getElementById("player1").style.top;
    value = value.replace("%", "");
    value = parseInt(value);
    value = value + 1;
    value = value + "%";
    document.getElementById("player1").style.top = value;
    

    … with this:

    var p1= document.getElementById('player1');
    p1.style.top= parseInt(p1.style.top)+1+'%';
    


    This calls the return result of player1MoveDown:

    setInterval(player1MoveDown(), 3000);
    

    Since player1MoveDown doesn't return anything, it's the equivalent of

    setInterval(null, 3000);
    

    To call the function every 3 seconds, do this instead:

    setInterval(player1MoveDown, 3000);
    


    This creates an infinite loop:

    x = 1;
    do {
      setInterval(player1MoveDown, 3000);
    }   
    while (x == 1);
    

    Even though keyup will set the global x to 0, it will never run because the loop never ends.

    Instead, create a timer variable, which is set on keydown and cleared on keyup.


    Complete JavaScript Code

    var timer;
    
    function player1MoveDown() {
      var p1= document.getElementById('player1');
      p1.style.top= parseInt(p1.style.top)+1+'%';
      console.log(p1.style.top);
    }
    
    function player1MoveSetting() {
      if(timer) return;
      timer= setInterval(player1MoveDown, 100);
    }
    
    function player1Stop() {
      clearInterval(timer);
      timer= null;
    }
    
    document.getElementById('player1').focus();
    

    Working Fiddle