如何重置Div至初始位置?足球游戏球复位失败问题排查
问题描述
开发一款足球游戏时遇到以下问题:球的div初始位于开球线位置,点击射门后会向鼠标点击位置移动,但射门完成后无法复位到初始位置。我在JS文件加载时用getBoundingClientRect()获取了球的初始位置,编写了restoreBallPositions方法,试图通过延迟设置top和left属性回到保存的ballRect位置,但该方法完全无效,不清楚原因。
代码片段
JavaScript 代码
const ball = document.getElementById('ball'); const ballRect = ball.getBoundingClientRect(); console.log(ballRect); function goal() { var score = getScore(); increaseDifficulty(score) document.getElementById("score").innerHTML = score + 1; var b = getShotCordinates(); moveBall(b[0], b[1]); restoreBallPositions(); } function save() { resetScore(); resetDifficulty(); restoreBallPositions(); } function resetScore() { document.getElementById("score").innerHTML = 0; } function getScore() { return parseInt(document.getElementById("score").innerHTML); } function increaseDifficulty(score) { switch (score) { case 5: document.getElementById("goalkeeper").style.animation = "protect 8s infinite"; break; case 10: document.getElementById("goalkeeper").style.animation = "protect 6s infinite"; break; case 15: document.getElementById("goalkeeper").style.animation = "protect 4s infinite"; break; case 20: document.getElementById("goalkeeper").style.animation = "protect 3s infinite"; break; case 25: document.getElementById("goalkeeper").style.animation = "protect 2s infinite"; break; case 30: document.getElementById("goalkeeper").style.animation = "protect 1s infinite"; break; default: } } function resetDifficulty() { document.getElementById("goalkeeper").style.animation = "protect 10s infinite"; } function moveBall(x, y) { var x = x - 150; var y = y - 450; document.getElementById("ball").style.transform = "translate(" + x + "px," + y + "px)"; document.getElementById("ball").style.transition = "0.2s"; } function getShotCordinates() { var e = window.event; var Cordinates = [e.clientX, e.clientY]; console.log(Cordinates[0] + " - " + Cordinates[1]) return Cordinates; } function restoreBallPositions() { setTimeout(function() { ball.style.top = ballRect.y; ball.style.top = ballRect.x; }, 2000); }
HTML 代码
<HTML lang="en"> <HEAD> <title>Soccor Game</title> <link rel='stylesheet' href='css/styles.css'> </HEAD> <BODY> <div id="canvas" class="field" onload="savePositions()"> <div id="goals" class="goals" onclick="goal()"></div> <div id="goalkeeper" onclick="save()"></div> <div id="kick-off"> <div id="ball" class="ball"></div> </div> <div id="score-container"> <div id="counter"> <h1 class="counter-text">Score</h1> <h1 class="counter-score" id="score">0</h1> </div> </div> </div> <script src='js/script.js'></script> </BODY> </html>
问题分析与修复方案
核心问题点
- 复位逻辑语法错误:
restoreBallPositions里连续两次设置ball.style.top,完全遗漏了left属性的设置;而且ballRect.y和ballRect.x是纯数值,没有添加单位px,浏览器无法识别该样式值。 - 移动方式不匹配:
moveBall方法是通过transform: translate()来移动球的,这种方式不会改变元素的top/left属性,反而会覆盖定位的位置。所以用设置top/left的方式无法抵消transform的位移效果。
修复后的restoreBallPositions方法
直接清除球的transform样式,就能让它回到父元素#kick-off定位的初始位置,这是最简单有效的方式:
function restoreBallPositions() { setTimeout(function() { ball.style.transform = 'none'; }, 2000); }
额外优化建议
getShotCordinates依赖window.event,兼容性较差,改为接收事件参数更稳妥:
function getShotCordinates(e) { var coordinates = [e.clientX, e.clientY]; console.log(coordinates[0] + " - " + coordinates[1]) return coordinates; } // 调用时传入事件 function goal(e) { // ...其他代码 var b = getShotCordinates(e); // ...其他代码 } // HTML里修改点击事件 <div id="goals" class="goals" onclick="goal(event)"></div>
内容的提问来源于stack exchange,提问作者GrahamNorton
相关产品推荐
相关产品推荐

