JS多按钮颜色切换函数仅同按钮点击正常 跨按钮进入最后else如何修复
问题根因
- 核心错误是**
counterr为全局共享变量**,没有和单个按钮绑定:点击第一个按钮修改了全局counterr的状态后,再点击其他按钮时读取的是前一次修改后的全局值,自然无法匹配预期的分支条件。 - 冗余请求:每次点击按钮都会重复请求
games.json,不仅性能差,也可能因为异步请求返回顺序异常导致逻辑错乱。 - 隐式全局变量风险:
getBetNumbers的for循环中i没有声明,会被挂载到window成为全局变量,可能引发其他遍历逻辑异常。 - 分支冗余:不同彩票类型的逻辑高度重复,可维护性极低,且原有错误处理逻辑写反(
err === null时才打印错误,和异步回调的常规约定完全相反)。 - 选中列表逻辑错误:原有取消选中时直接删除列表最后一个元素,和当前点击的按钮没有关联,点击不同按钮时会误删其他选中值。
修复方案
优化逻辑思路
- 提前请求并缓存
games.json的配置,避免重复请求 - 每个按钮的选中状态存在元素自身的
dataset属性中,不再共用全局counterr - 用配置映射表替代多分支
else if判断,简化逻辑 - 修复变量作用域、错误处理、选中列表操作的逻辑问题
修复后代码
提前缓存全局配置
// 提前缓存彩票配置,避免每次点击重复请求 let lotteryConfig = null getDescription('games.json', function (err, data) { if (err) { console.log('Ocorreu um erro' + err) return } lotteryConfig = data }) // 全局仅保留需要共享的选中计数、选中列表、当前彩票类型 let counterNumbers = 0 let totalNumbers = [] let whichLoteriaIs = 'lotofacil' // 按实际业务逻辑赋值即可
优化getBetNumbers函数
function getBetNumbers(num) { const ext = document.getElementById('ext'); ext.innerHTML = ''; // 声明i为局部变量,避免隐式全局污染 for (let i = 1; i <= num; i++) { const showText = i < 10 ? `0${i}` : String(i) // 选中状态存在dataset.isActive中,默认未选中 ext.innerHTML += `<div onclick="changeButtonColor(${i})" class="quina" data-numbers="data${i}" id="ext${i}" data-is-active="false">${showText}</div>` } }
重写changeButtonColor函数
const changeButtonColor = function (number) { // 配置未加载完成直接返回 if (!lotteryConfig) return const ext = document.getElementById('ext' + number) const isActive = ext.dataset.isActive === 'true' // 彩票类型和配置的映射表,后续新增类型只需在这里加配置即可 const lotteryMap = { lotofacil: { maxCount: 15, color: lotteryConfig.types[0].color }, megasena: { maxCount: 6, color: lotteryConfig.types[1].color }, lotomania: { maxCount: 20, color: lotteryConfig.types[2].color }, quina: { maxCount: 5, color: lotteryConfig.types[3].color } } const currentLottery = lotteryMap[whichLoteriaIs] if (!currentLottery) return if (isActive) { // 已选中状态,点击后取消选中 ext.style.backgroundColor = '#ADC0C4' ext.dataset.isActive = 'false' counterNumbers-- // 从选中列表移除当前点击的号码,避免误删其他值 const idx = totalNumbers.findIndex(item => item === ext.innerText) if (idx > -1) totalNumbers.splice(idx, 1) } else { // 未选中状态,先判断是否超过当前彩票类型的最大可选数 if (counterNumbers >= currentLottery.maxCount) return // 执行选中逻辑 ext.style.backgroundColor = currentLottery.color ext.dataset.isActive = 'true' counterNumbers++ totalNumbers.push(ext.innerText) } }
内容的提问来源于stack exchange,提问作者Guilherme
相关产品推荐
相关产品推荐

