You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何简单重置DOM解决JS单词猜谜游戏重置后的各类异常问题?

问题根因与修复代码

三个问题的核心都来自状态重置不彻底、事件重复绑定、内联样式优先级过高:

  • 问题1:每次重置调用ans()时会给所有字母按钮重复绑定点击事件,多次绑定后点击一次按钮会触发多次回调,同时部分按钮移除事件的逻辑混乱,导致无法点击
  • 问题2:直接设置按钮的内联背景色优先级高于CSS的hover规则,导致hover失效
  • 问题3:事件重复绑定后,单次点击会触发多次错误判断逻辑,导致尝试次数异常扣减,同时未清理的游戏结束定时器也可能在重置后异常修改次数值

第一步:新增CSS类(替换原内联改背景的逻辑)

/* 加到你的样式文件里 */
.letter-btn.disabled {
  background-color: grey;
  pointer-events: none;
}

用类控制禁用状态,不会覆盖hover样式,同时自动禁止点击,不需要手动移除/绑定事件。

第二步:修改后的完整JS代码

// 词库
const words = [ "planet", "stars", "astroid", "moon", "satilite", "orbit", "universe", "umbra", "lunar", "space", "astronomy", "eclipse", "nebula", "mars", "meteorite"];

// 已猜字母数组
let myGuesses = [];

// 通用变量
let wordSpace = " - ";
let guess = " ";
let space; // 单词的空格数量

// 分数相关
let tries = 10;
let counter;
// 存储定时器ID,避免重置后旧定时器触发
let gameEndTimer = null;
// 取随机词下标
let index = Math.floor(Math.random() * words.length);

// 游戏启动函数
function play(isReset = false) {
  // 只在第一次进入游戏弹提示,重置的时候不重复弹
  if (!isReset) {
    let userInput = prompt(`你想要玩太空人猜词游戏吗?(Y/N)`, "Y");
  }
  console.log(words[index]);

  for (let i = 0; i < words[index].length; i++) {
    let div = document.createElement("div");
    div.classList.add("letters");
    div.innerHTML = " - ";
    document.querySelector(".word-space").append(div);
  }
}
// 点击事件处理函数,点击后将按钮标记为已用
let handleclick = (e) => {
  e.target.classList.add('disabled');
  console.log(e.target.innerHTML);
  myGuesses.push(e.target.innerHTML);
  console.log(myGuesses);
  console.log(words[index].includes(e.target.innerHTML));
  if (words[index].includes(e.target.innerHTML)) {
    document.querySelector(".word-space").innerHTML = "  ";

    for (let i = 0; i < words[index].length; i++) {
      let div = document.createElement("div");
      div.classList.add("letters");
      if (myGuesses.includes(words[index][i])) {
        div.innerHTML = words[index][i];
      } else {
        div.innerHTML = " - ";
      }

      document.querySelector(".word-space").append(div);
    }
    getNumOfTries();
  } else {
    tries--;
    getNumOfTries();
  }
};

function ans() {
  const buttons = document.querySelectorAll("button.letter-btn");
  buttons.forEach((button) => {
    // 先移除旧的事件,避免重复绑定
    button.removeEventListener("click", handleclick);
    button.addEventListener("click", handleclick);
  });
}
ans();

function getNumOfTries() {
  console.log(tries);
  const showTries = document.querySelector("#myTries");
  showTries.innerHTML = " 你还有 " + tries + " 次机会";
  // 先清掉之前的定时器
  if (gameEndTimer) clearTimeout(gameEndTimer);
  if (tries < 1) {
    gameEndTimer = setTimeout(() => {
      prompt(`你想要再试一次吗?(Y,N)`, "Y");
      showTries.innerHTML = "你输了!";
    }, 2000);
  }
  Array.from(document.querySelectorAll(".letters")).forEach((letter) => {
    console.log(letter.innerHTML);
  });
  if (
    tries > 0 &&
    Array.from(document.querySelectorAll(".letters")).every(
      (letter) => letter.innerHTML !== " - "
    )
  ) {
    gameEndTimer = setTimeout(() => {
      alert(`你赢了!`);
      showTries.innerHTML = "你赢了!";
    }, 1000);
  }
}

// 游戏重置逻辑
let tryAgain = document.querySelector(".Try-Again");
tryAgain.addEventListener("click", () => {
  // 清旧定时器
  if (gameEndTimer) clearTimeout(gameEndTimer);
  myGuesses = [];
  tries = 10;
  wordSpace = " - ";
  index = Math.floor(Math.random() * words.length);
  document.querySelector(".word-space").innerHTML = "";
  let showTries = document.querySelector("#myTries");
  showTries.innerHTML = "再试一次";
  let buttons = document.querySelectorAll("button.letter-btn");
  buttons.forEach((button) => {
    // 移除禁用类,恢复默认样式和点击能力
    button.classList.remove('disabled');
  });

  ans();
  // 重置的时候传参数,不重复弹初始提示
  play(true);
});

play();

注意:请给所有字母按钮加上letter-btn类,避免重置逻辑影响到.Try-Again重置按钮。

内容的提问来源于stack exchange,提问作者Tamara

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.25 18:54:01