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

JavaScript按钮数组存储与调用失效问题求助

选号功能实现问题

我开发的选号功能需求:从表格最多选5个按钮,点击第6个时,将最早选中的按钮设为disabled状态并移除绿色样式,同时选中当前按钮。页面加载时通过JavaScript生成带按钮的表格,例如选中1-2-3-4-5后点击6,1需被禁用且不再计入选中项。

尝试用数组存储选中按钮,但点击第5个按钮时报错:

Uncaught TypeError: Cannot read properties of undefined (reading 'button')
at button.onclick

怀疑数组存储或访问方式有误(代码中使用firstButton = array_btn[previous].button),现求助实现该功能的方案,相关代码如下:

原HTML代码

<!DOCTYPE html>
<html lang="it">
  <head>
    <meta charset="UTF-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Lotto</title>
    <link rel="stylesheet" href="stile.css" />
    <style>
      @import url("https://fonts.googleapis.com/css2?family=Josefin+Sans&display=swap");
      @import url("https://fonts.googleapis.com/css2?family=Inter&display=swap");
    </style>
    <script src="lotto.js"></script>
  </head>
  <body onload="createTable()">
    <h1>Benvenuto all'Enalotto !</h1>
    <p class="istruzioni">
      Seleziona dalla tabella sottostante i numeri che vuoi giocare (MASSIMO 5
      !)
    </p>
    <br />
    <table id="tab-punt" class="tabella"></table>
    <br /><br />
    <p id="stampa" class="punt">Stai puntando i seguenti numeri :</p>
    <button onclick="randomArray(); check();" class="bottone" id="btnvinto">
      Scopri se hai vinto !
    </button>
    <p id="vincenti" class="vincenti"></p>
    <p id="vinto" class="perso"></p>
    <br /><br />
  </body>
</html>

原JavaScript代码

let num = 1;
function createTable() {
  let tabella = document.getElementById("tab-punt");

  for (let i = 0; i < 10; i++) {
    let nuovaRiga = tabella.insertRow(-1);

    for (let j = 0; j < 9; j++) {
      let nuovaCella = nuovaRiga.insertCell(j);
      nuovaCella.appendChild(createButton(num));
      num += 1;
    }
  }
}

//Creating arrays to store user input
const input = new Array(5);

var click_counter = 0;
var stringa_out = "";
var i = 0;

let lastButton;
let array_btn = [];
let previous;

//Function to create every single button
function createButton(index) {
  let button = document.createElement("BUTTON");
  button.classList.add("bot-tab");
  //All buttons will share this class
  button.classList.add("click");
  var text = document.createTextNode(index);
  button.appendChild(text);

  button.onclick = function () {
    let firstButton;
    let currentButton;
    currentButton = this;
    array_btn.push({ currentButton });
    input[i] = index;
    i += 1;
    button.classList.add("verde");
    click_counter += 1;
    if (click_counter === 5) {
      firstButton = array_btn[previous].button;
      firstButton.disabled = true;
      //lastButton = button;
      firstButton.classList.remove("verde");
      click_counter -= 1;
      previous+=1;
    }
  };

  return button;
}

问题分析与修复方案

核心错误点

  1. previous变量未初始化,默认是undefined,导致array_btn[previous]取到undefined,访问.button属性触发报错。
  2. 数组存储的是{ currentButton }对象,但访问时错误使用.button,应该用.currentButton。
  3. 逻辑判断错误:应该在选中第6个按钮时执行替换逻辑,而非第5个。
  4. input数组和i变量逻辑混乱,易导致数组越界或存储错误。

修复后的完整JavaScript代码

let num = 1;
function createTable() {
  let tabella = document.getElementById("tab-punt");

  for (let i = 0; i < 10; i++) {
    let nuovaRiga = tabella.insertRow(-1);

    for (let j = 0; j < 9; j++) {
      let nuovaCella = nuovaRiga.insertCell(j);
      nuovaCella.appendChild(createButton(num));
      num += 1;
    }
  }
}

// 存储当前选中的按钮(最多5个)
const selectedButtons = [];

// 创建单个按钮的函数
function createButton(index) {
  let button = document.createElement("BUTTON");
  button.classList.add("bot-tab");
  button.classList.add("click");
  button.textContent = index;

  button.onclick = function () {
    // 跳过已选中或禁用的按钮
    if (selectedButtons.includes(this) || this.disabled) return;

    // 添加当前按钮到选中列表
    selectedButtons.push(this);
    this.classList.add("verde");

    // 超过5个时,移除最早选中的按钮
    if (selectedButtons.length > 5) {
      const oldestButton = selectedButtons.shift(); // 取出数组第一个元素(最早选中的)
      oldestButton.disabled = true;
      oldestButton.classList.remove("verde");
    }

    // 更新页面上的选中号码显示
    updateSelectedNumbers();
  };

  return button;
}

// 更新页面上选中号码的显示
function updateSelectedNumbers() {
  const displayElement = document.getElementById("stampa");
  const numbers = selectedButtons.map(btn => btn.textContent).join(", ");
  displayElement.textContent = `Stai puntando i seguenti numeri : ${numbers}`;
}

修复说明

  1. 用selectedButtons数组直接存储按钮DOM元素,无需包装对象,简化操作。
  2. 点击按钮时先判断状态,避免重复选中或操作禁用按钮。
  3. 选中数量超过5时,用shift()直接取出最早选中的按钮,自动维持数组最多5个元素。
  4. 新增updateSelectedNumbers函数同步更新页面显示,提升用户体验。
  5. 移除原代码中逻辑混乱的冗余变量,简化整体逻辑。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.06 22:15:27