Vanilla JS游戏启动后立即跳转结束页,求Timeout问题排查解决
问题分析与解决方案
嘿,我一眼就看到你遇到的核心问题了——游戏刚启动就跳转到结束页面,主要是setTimeout的调用方式错误,再加上逻辑结构混乱导致的,咱们一步步来修复:
1. 最致命的错误:setTimeout立即执行了endGame
你写的setTimeout(endGame(), 5000);里,endGame()是直接调用函数,而不是把函数作为参数传给setTimeout。这就导致代码执行到这里时,会立刻触发endGame跳转页面,完全不会等5秒。
正确写法应该是传函数引用(不带括号):
timer = setTimeout(endGame, 5000);
2. 倒计时的作用域问题
原来的timer是countdown函数的局部变量,每次调用countdown都会生成新的timer。当你点击按钮时,新调用的countdown根本拿不到之前启动倒计时的那个timer,所以clearTimeout根本起不到清除倒计时的作用。
解决方法是把timer和当前需要点击的目标颜色都放到全局作用域,让所有函数都能访问到。
3. 逻辑职责混乱
原来的countdown既负责启动倒计时,又负责判断点击是否正确,这会导致逻辑冲突:比如启动游戏时调用countdown,此时click参数是undefined,color == click永远不成立,而且还会立刻触发错误的endGame调用。
咱们需要拆分逻辑:
- 用全局变量保存当前需要点击的目标颜色
- 点击按钮时单独判断是否点击正确
- 倒计时只负责超时后结束游戏
修正后的完整代码
JavaScript 代码
// 全局变量:保存当前需要点击的颜色、倒计时ID let currentTargetColor; let timer; // 启动游戏 function start() { getCommand(); document.getElementById("start").hidden = true; } // 生成随机目标颜色与文字颜色 function getCommand() { // 生成需要点击的按钮颜色 const computer = Math.floor(Math.random() * 3) + 1; switch (computer) { case 1: currentTargetColor = "blue"; break; case 2: currentTargetColor = "red"; break; case 3: currentTargetColor = "yellow"; break; } // 生成文字显示颜色 const computerB = Math.floor(Math.random() * 3) + 1; let textColor; switch (computerB) { case 1: textColor = "#0000ff"; break; case 2: textColor = "#ff0000"; break; case 3: textColor = "#ffff00"; break; } // 更新页面显示内容 const displayEl = document.getElementById("display"); displayEl.innerHTML = currentTargetColor; displayEl.style.color = textColor; // 启动新一轮倒计时(先清除之前的防止重复) startCountdown(); } // 启动倒计时 function startCountdown() { if (timer) clearTimeout(timer); timer = setTimeout(endGame, 5000); // 正确传递函数引用 } // 检查按钮点击是否正确 function checkClick(clickedColor) { if (clickedColor === currentTargetColor) { // 点击正确:清除当前倒计时,生成新目标 clearTimeout(timer); getCommand(); } else { // 点击错误:直接结束游戏 endGame(); } } // 结束游戏跳转 function endGame() { window.location.href = "endGame.html"; }
HTML 按钮部分调整
把原来按钮的onclick="countdown(\"red\")"改成调用checkClick函数:
<div id="buttons"> <img src="images/redButton.png" alt="" width="120px" id="redButton" onclick="checkClick('red')" onmousedown="clickSwapRed()" onmouseup="swapBackRed()"> <img src="images/blueButton.png" alt="" width="120px" id="blueButton" onclick="checkClick('blue')" onmousedown="clickSwapBlue()" onmouseup="swapBackBlue()"> <img src="images/yellowButton.png" alt="" width="120px" id="yellowButton" onclick="checkClick('yellow')" onmousedown="clickSwapYellow()" onmouseup="swapBackYellow()"> </div>
修正后的游戏流程
- 点击
Start Game按钮后,隐藏按钮并生成随机目标颜色与文字颜色,显示在页面上 - 启动5秒倒计时,超时则自动跳转到结束页面
- 点击按钮时,判断点击颜色是否与目标颜色一致:
- 一致:清除当前倒计时,生成新的目标颜色,开始新一轮游戏
- 不一致:直接跳转到结束页面
这样修改后,游戏就能正常运行啦!
内容的提问来源于stack exchange,提问作者Jason Casebier
相关产品推荐
相关产品推荐

