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; }
问题分析与修复方案
核心错误点
previous变量未初始化,默认是undefined,导致array_btn[previous]取到undefined,访问.button属性触发报错。- 数组存储的是
{ currentButton }对象,但访问时错误使用.button,应该用.currentButton。 - 逻辑判断错误:应该在选中第6个按钮时执行替换逻辑,而非第5个。
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}`; }
修复说明
- 用
selectedButtons数组直接存储按钮DOM元素,无需包装对象,简化操作。 - 点击按钮时先判断状态,避免重复选中或操作禁用按钮。
- 选中数量超过5时,用
shift()直接取出最早选中的按钮,自动维持数组最多5个元素。 - 新增
updateSelectedNumbers函数同步更新页面显示,提升用户体验。 - 移除原代码中逻辑混乱的冗余变量,简化整体逻辑。
内容的提问来源于stack exchange,提问作者Lvcaa
相关产品推荐
相关产品推荐

