复刻Chrome断网恐龙游戏时出现双击跳跃异常问题求助
排查Chrome恐龙游戏复刻中点击触发两次跳跃的问题
问题概述
复刻Chrome断网时的恐龙游戏开发中,点击屏幕后角色出现两次跳跃的异常效果,不符合预期单次跳跃的需求。以下是问题代码及排查分析:
问题代码
JavaScript
var character = document.getElementById("character"); var block = document.getElementById("block"); function jump() { if (character.classList != "animate") { character.classList.add("animate"); } setTimeout(function() { character.classList.remove("animate"); }, 500); }
CSS
* { padding: 0; margin: 0; height: 100vh; align-items: center; justify-content: center; } #game { width: 500px; height: 200px; border: 1px solid black; } #character { width: 20px; height: 50px; background-color: red; position: relative; top: 150px; } .animate { animation: jump 500ms; } #block { width: 20px; height: 20px; background-color: blue; position: relative; top: 130px; left: 480px; animation: block 1s infinite; } @keyframes jump { 0% { top: 100px; } 50% { top: 150px; } 100% { top: 100px; } } @keyframes block { 0% { left: 480px; } 100% { left: -40px } }
HTML
<!DOCTYPE html> <html lang="en" onclick="jump()"> <head> <meta http-equiv="content-type" content="text/html; charset=utf-8" /> <title>Dino Game</title> <link rel="stylesheet" href="style.css"> </head> <body> <div id="game"> <div id="character"></div> <div id="block"> </div> </div> <script src="main.js"></script> </body> </html>
问题原因
- 动画关键帧逻辑颠倒:角色初始位置为
top:150px,但@keyframes jump设置0%为top:100px、50%为top:150px、100%为top:100px,导致动画执行时角色先从初始位置跳到100px,落回150px后又跳回100px,视觉上呈现两次跳跃。 - Class存在性判断错误:使用
character.classList != "animate"进行判断是无效的——classList是DOMTokenList对象,并非字符串,该条件永远为true,导致动画执行中再次点击会重复添加类,可能引发动画叠加。 - 全局事件绑定风险:将点击事件绑定在
<html>标签上,点击页面任意区域都会触发跳跃,若存在元素嵌套冒泡异常,可能间接导致jump函数多次调用。
解决方案及修正代码
1. 修正动画关键帧
让角色从初始位置起跳,到达最高点后落回初始位置:
@keyframes jump { 0% { top: 150px; /* 初始位置 */ } 50% { top: 100px; /* 跳跃最高点 */ } 100% { top: 150px; /* 落回初始位置 */ } }
2. 修复Class判断逻辑
使用classList.contains()正确检测类是否存在:
var character = document.getElementById("character"); var block = document.getElementById("block"); function jump() { if (!character.classList.contains("animate")) { character.classList.add("animate"); setTimeout(function() { character.classList.remove("animate"); }, 500); } }
3. 优化事件绑定范围
将点击事件绑定到游戏容器#game,缩小触发范围,避免全局误触:
<!DOCTYPE html> <html lang="en"> <head> <meta http-equiv="content-type" content="text/html; charset=utf-8" /> <title>Dino Game</title> <link rel="stylesheet" href="style.css"> </head> <body> <div id="game" onclick="jump()"> <div id="character"></div> <div id="block"> </div> </div> <script src="main.js"></script> </body> </html>
4. 修正全局CSS样式
移除*选择器的无效属性,给body设置flex实现游戏容器居中:
* { padding: 0; margin: 0; } body { height: 100vh; display: flex; align-items: center; justify-content: center; } #game { width: 500px; height: 200px; border: 1px solid black; } #character { width: 20px; height: 50px; background-color: red; position: relative; top: 150px; } .animate { animation: jump 500ms; } #block { width: 20px; height: 20px; background-color: blue; position: relative; top: 130px; left: 480px; animation: block 1s infinite; } @keyframes block { 0% { left: 480px; } 100% { left: -40px } }
内容的提问来源于stack exchange,提问作者catthatmeows_
相关产品推荐
相关产品推荐

