原生JS实现双列表圣诞礼物抽签 如何避免参与者抽中自己
圣诞礼物抽签程序Bug修复方案
原有代码问题梳理
- 循环条件错误:
drawLotsBTN监听事件中的for循环条件写为赋值语句i = Players2.length,无法按预期遍历玩家 - 校验逻辑不符合业务要求:原判断
randomPerson != Players.indexOf(i)逻辑完全错误,i是循环索引,你实际需要校验的是「当前待分配的玩家」和「随机抽到的玩家」是否为同一人 - 无兜底逻辑:如果抽签到最后仅剩的一个名额刚好是玩家自己,会进入死循环
修复后的核心代码
直接替换drawLotsBTN的点击事件代码即可:
drawLotsBTN.addEventListener('click', function() { // 清空上一次抽签结果 playersList2.innerHTML = ''; // 临时抽签池,避免直接修改Players2出问题方便重试 let drawPool = JSON.parse(JSON.stringify(Players2)); let drawResult = []; let drawSuccess = true; for (let i = 0; i < Players.length; i++) { // 当前要分配赠送对象的玩家 let currentPlayer = Players[i]; // 过滤掉自己,只保留可抽取的名额 let availableList = drawPool.filter(item => item !== currentPlayer); if (availableList.length === 0) { // 仅剩自己,分配失败触发重试 drawSuccess = false; break; } // 随机抽取 let randomIndex = Math.floor(Math.random() * availableList.length); let pickedPerson = availableList[randomIndex]; drawResult.push(pickedPerson); // 从抽签池移除已经被抽走的人员 drawPool.splice(drawPool.indexOf(pickedPerson), 1); } if (!drawSuccess) { // 自动重试抽签 this.click(); return; } // 渲染结果到右侧列表 drawResult.forEach(person => { playersList2.innerHTML = playersList2.innerHTML + "<br>" + person; }); // 禁用按钮避免重复点击 this.disabled = true; });
额外优化建议
- 建议限制参与者至少3人及以上再允许启动抽签,2人场景下必然出现互抽,1人场景永远无法满足不抽中自己的规则
- 可以在启动抽签前先判断
Players.length,小于3就给出对应提示
内容的提问来源于stack exchange,提问作者Kolekcja Kolekcja
相关产品推荐
相关产品推荐

