在JavaScript中,一键启动事件只工作一次



我正在尝试创建一个JavaScript游戏。在那里,我创建了一个函数,每当我们按下向右箭头键时,DIV都应该向右移动。当我第一次按下它时,它工作得很好。然而,当我在那之后按下它时,它不起作用。这是我迄今为止尝试过的代码:

<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>

我在这里做错了什么?如有任何帮助,我们将不胜感激。谢谢!

style.left是一个带单位的字符串属性(即:"10px">(。要添加或获取单位,您首先需要将其解析为一个数字或使用另一个属性(即:offsetLeft(,然后将其与单位一起赋值。

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>

修改代码以处理left属性的后缀px

<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>

使函数递归,这样在每次单击事件时,它都会自动移动,而不会刷新为首字母。

第一次修改后,左侧属性的值为字符串"10px"。因此,要继续添加值,您需要在添加新值之前提取该值,例如:

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

("||0"用于第一次迭代,因为它接收到一个空字符串(

// 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";
}

工作示例

我们需要将style.left从String数据类型转换为Number数据类型,以便增加或减少值。

第一次修改后,左侧属性的值为字符串"10px"。

因此,当您在第一次修改后尝试将style.left增加数字10时,它将变为10px10,这不是style.left属性的有效值。这就是为什么它只是第一次起作用。

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;
}

最新更新