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

求助:如何用Javascript实现数字方块按顺序点击的交互逻辑

顺序点击校验逻辑实现方案

我正在开发一款数字点击游戏,方块已能随机显示1-25的数字、随机颜色和字体大小。现在需要实现顺序点击校验逻辑:

  • 数字1始终可点击
  • 数字2需在数字1被点击后才可点击,数字3需在1和2都点击后才可点击,以此类推
  • 成功点击后方块背景色改变

之前尝试的代码出现问题:

if (squares[i].textContent = numArray[i] === 1) squares[i].addEventListener('click', function() { return squares[i].style.backgroundColor = 'red'})

这段代码把numArray[i] === 1的布尔结果赋值给了squares[i].textContent,导致方块显示true/false而非数字,同时无法实现后续的顺序校验。


核心思路

  1. 新增全局变量currentTarget,记录当前需要点击的目标数字(初始值为1)
  2. 给所有方块绑定统一的点击事件,在事件中校验当前方块的数字是否等于currentTarget
  3. 校验通过后,更新方块背景色,并将currentTarget加1,直到完成所有数字点击

修改后的完整代码

JavaScript代码

let startBtn = document.querySelector('.start-btn')
let resetBtn = document.querySelector('.reset-btn')
let timer = document.querySelector('.time__countdown')
const squares = [...document.querySelectorAll('.square')];
let gameStarted = false;
let counter = 60
let timeInterval;
let currentTarget = 1; // 当前需要点击的目标数字

startBtn.addEventListener('click', startGame)

function startGame() {
  gameStarted = true;
  currentTarget = 1; // 重置目标数字

  // 统一绑定点击事件(避免重复绑定,先移除再添加)
  squares.forEach(square => {
    square.removeEventListener('click', handleSquareClick);
    square.addEventListener('click', handleSquareClick);
  });

  randomNumber()

  timeInterval = setInterval(function() {
    counter--
    if (counter >= 0) {
      timer.innerHTML = `Time left: ${counter}`
    } else {
      clearInterval(timeInterval);
      alert('时间到!游戏结束');
    }
  }, 1000)
}

// 方块点击处理函数
function handleSquareClick() {
  if (!gameStarted) return;
  
  const clickedNum = parseInt(this.textContent);
  if (clickedNum === currentTarget) {
    // 点击正确,修改背景色
    this.style.backgroundColor = '#2A3166';
    // 禁用已点击的方块(可选,防止重复点击)
    this.style.pointerEvents = 'none';
    // 更新目标数字
    currentTarget++;
    
    // 检查是否完成所有数字点击
    if (currentTarget > 25) {
      clearInterval(timeInterval);
      alert('恭喜你完成所有数字点击!');
      gameStarted = false;
    }
  }
}

function getRandomColor() {
  const letters = '0123456789ABCDEF';
  let color = '#';
  for (let i = 0; i < 6; i++) {
    color += letters[Math.floor(Math.random() * 16)];
  }
  return color;
}

function randomNumber() {
  const numArray = []

  for (let i = 1; i < 26; i++) {
    numArray.push(i)
  }

  numArray.sort(() => 0.5 - Math.random())

  for (let i = 0; i < squares.length; i++) {
    const random = Math.floor(Math.random() * 25)
    squares[i].textContent = numArray[i]
    squares[i].style.fontSize = random + 15 + "px";
    squares[i].style.color = getRandomColor()
    squares[i].style.backgroundColor = '#000000';
    squares[i].style.pointerEvents = 'auto'; // 重置点击状态
  }
}

resetBtn.addEventListener('click', function() {
  clearInterval(timeInterval)
  counter = 60
  timer.innerHTML = `Time left: 60`
  gameStarted = false
  currentTarget = 1; // 重置目标数字
  squares.forEach((n) => {
    n.textContent = "";
    n.style.backgroundColor = "#000000";
    n.style.pointerEvents = 'auto'; // 重置点击状态
  })
})

CSS代码

* {
  margin: 0;
  padding: 0;
}

body,
html {
  min-width: 100%;
  min-height: 100vh;
  box-sizing: border-box;
  font-size: 100%;
  display: flex;
  justify-content: center;
  align-items: center;
  background-color: black;
}

img {
  max-width: 100%;
  display: block;
}

main {
  display: flex;
  flex-direction: column;
  justify-content: center;
  align-items: center;
  width: 24%;
  background-color: #6688CC;
  border-radius: 10px;
}

.grid {
  border: 2px solid black;
  width: 100%;
  display: flex;
  flex-wrap: wrap;
  background-color: #ACBFE6;
  justify-content: center;
  align-items: center;
  gap: 2px;
  padding-top: 3px;
  padding-bottom: 3px;
}

.square {
  border: 2px solid black;
  width: 70px;
  height: 70px;
  display: flex;
  justify-content: center;
  align-items: center;
  background-color: #000000;
  color: white; /* 确保数字默认可见 */
  cursor: pointer; /* 鼠标悬停显示指针 */
}

.time {
  padding-bottom: 2em;
  padding-top: 1em;
}

.btn {
  margin: 1em;
  padding: 0.5em 1em;
  cursor: pointer;
}

.buttons {
  display: flex;
}

HTML代码

<main>
  <div class="time">
    <p class="time__countdown">Time left: 60</p>
  </div>
  <div class="grid">
    <div class="square"></div>
    <div class="square"></div>
    <div class="square"></div>
    <div class="square"></div>
    <div class="square"></div>
    <div class="square"></div>
    <div class="square"></div>
    <div class="square"></div>
    <div class="square"></div>
    <div class="square"></div>
    <div class="square"></div>
    <div class="square"></div>
    <div class="square"></div>
    <div class="square"></div>
    <div class="square"></div>
    <div class="square"></div>
    <div class="square"></div>
    <div class="square"></div>
    <div class="square"></div>
    <div class="square"></div>
    <div class="square"></div>
    <div class="square"></div>
    <div class="square"></div>
    <div class="square"></div>
    <div class="square"></div>
  </div>
  <div class="buttons">
    <button class="btn start-btn">Start Game</button>
    <button class="btn reset-btn">Reset Game</button>
  </div>
</main>

关键修改点说明

  • 新增currentTarget变量追踪当前需要点击的数字,初始值为1
  • 统一使用handleSquareClick函数处理所有方块点击,避免重复绑定事件
  • 点击时先将方块文本转为整数,再与currentTarget对比,校验通过后更新背景色并递增目标数字
  • 添加了时间到和完成所有点击的提示,提升游戏体验
  • 重置游戏时恢复方块的点击状态,避免下次游戏无法点击
  • 修复了原代码中grid标签的错误(改为标准div标签)

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.10 03:35:25