简体   繁体   中英

On key up event working only once in JavaScript

I am trying to create a JavaScript game. There, I have created a function that whenever we press the right arrow key, the DIV should move to the right. When I press it for the first time, it works fine. However, when I press it after that, it does not work. Here is the code I have tried so far:

 <html> <head> <style>.runobj { width: 80px; height: 80px; position: absolute; background-color: #00ff00; top: 0; left: 0; } </style> </head> <body onkeydown="moveObj(event)"> <div class="runobj" id="runobj"></div> <script> function moveObj(event) { var runobj = document.getElementById("runobj"); if (event.keyCode === 37) { runobj.style.left -= 10; } else if (event.keyCode === 39) { runobj.style.left += 10; } } </script> </body> </html>

What am I doing wrong here? Any help would be appreciated. Thankyou!

style.left is a string property with a unit (ie: "10px" ). To add or take units of it you first need to parse it to a number or use another property (ie: offsetLeft ) and after assign it back with the unit.

 function moveObj(element, event){ console.log('keycode', event.keyCode); //REM: Looking up the same element all the time is not ideal. Maybe pass it instead? var runobj = element || document.getElementById("runobj"); //REM: You need to turn "style.left" into a number var tCurrentLeft = parseFloat(runobj.style.left) || 0; //REM: Just use a switch, since it looks like you are going to implement more key actions switch(event.keyCode){ case 37: //REM: Do not forget to add the unit runobj.style.left = tCurrentLeft - 10 + 'px'; break case 39: //REM: Do not forget to add the unit runobj.style.left = tCurrentLeft + 10 + 'px' }; console.log('left', runobj.style.left) }; //REM: It is better to fully split the javascript from the HTML markup. Also you can just pass the element and avoid lookups. window.addEventListener('keydown', moveObj.bind(this, document.getElementById("runobj")));
 .runobj { width: 80px; height: 80px; position: absolute; background-color: #00ff00; top: 0; left: 0; }
 <body> <div class="runobj" id="runobj"></div> </body>

Modified your code to handle the postfix px for left attribute:

 <html> <head> <style>.runobj { width: 80px; height: 80px; position: absolute; background-color: #00ff00; top: 0; left: 0; } </style> </head> <body onkeydown="moveObj(event)"> <div class="runobj" id="runobj"></div> <script> var _left = 0; function moveObj(event) { var runobj = document.getElementById("runobj"); if (event.keyCode === 37) { _left -= 10; } else if (event.keyCode === 39) { _left += 10; } runobj.style.left = _left + 'px'; } </script> </body> </html>

Make the function recursive so that on every click event it should moved automatically without refreshing it to the initials.

After the first modification, the value of the left property is the string '10px'. So to continue adding values, you need to extract that value before adding a new values, for example:

runobj.style.left = parseInt(runobj.style.left || 0, 10) + 10;

(The '|| 0' is for the first iteration, because it receives an empty string)

// cache the element
var runobj = document.getElementById("runobj");

function moveObj(event) {
  var left = runobj.getBoundingClientRect().left;

  if (event.keyCode === 37) {
    left -= 10;
  } else if (event.keyCode === 39) {
    left += 10;
  }

  runobj.style.left = left + "px";
}

Working example

We need to convert style.left from String datatype to Number datatype inorder to increment or decrement the value.

After the first modification, the value of the left property is the string '10px'.

So when you tried to increment style.left by number 10 after the first modification, it becomes 10px10 which is not a valid value for style.left property.That's why it only works for the first time.

var runobj = document.getElementById("runobj");
function moveObj(event) {

  /* Converting the left style value from String type to Number type.
  '|| 0' is for the first iteration, because it receives an empty string */

  var current = parseFloat(runobj.style.left) || 0;
  
  if (event.keyCode === 37) {
        current += 20;
      } else if (event.keyCode === 39) {
        current -= 20;
      }
      // Updating the value
      runobj.style.left = current;
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM