JS开发Simon颜色游戏时事件监听器变量修改不触发if判断问题
问题根因
和作用域无关,你的代码逻辑有三个明显漏洞:
- 页面加载完成首次调用
play()时,running变量只声明未赋值,初始值是undefined,running == true的判断不成立,四个彩色SVG按钮根本没绑定上点击事件 - 点击START按钮仅把
running设为了true,没有再次执行play()去绑定事件,所以彩色按钮全程没有监听器,点击自然没有任何反应 - 就算补了START回调里的
play()调用,还会出现两个衍生问题:每点一次START就会重复绑定一套监听器,最后点一次彩色按钮会触发多次逻辑;点击RESET把running改为false时,已经绑定的监听器不会自动失效,达不到禁用按钮的效果。
快速修复方案
不用推翻现有代码重写,直接调整gamePlay.js的逻辑即可:不用反复绑定/移除事件,页面初始化时就给所有彩色按钮绑定一次监听器,监听器运行时先判断游戏是否处于启动状态,未启动就直接终止逻辑,是最简单稳定的实现。
修改后的gamePlay.js完整代码:
const start = document.getElementById("start"); const reset = document.getElementById("reset"); const yellow = document.getElementById("yellow"); const blue = document.getElementById("blue"); const green = document.getElementById("green"); const red = document.getElementById("red"); var order = []; var selected = []; // 初始状态游戏未运行 var running = false; // 彩色按钮通用点击逻辑 function handleColorClick(color) { // 游戏未启动直接拦截,不执行后续操作 if (!running) return; console.log(`${color} 被点击`); selected.push(color); // 后续可在此追加答案校验、回合推进、按钮亮灯动效逻辑 } // 页面加载时一次性绑定所有彩色按钮事件,无需反复绑定/解绑 yellow.addEventListener('click', () => handleColorClick("yellow")); blue.addEventListener('click', () => handleColorClick("blue")); green.addEventListener('click', () => handleColorClick("green")); red.addEventListener('click', () => handleColorClick("red")); start.addEventListener('click', () => { running = true; // 可在此追加游戏初始化、生成第一轮序列、播放序列动效逻辑 console.log("游戏已启动"); }); reset.addEventListener('click', () => { running = false; order = []; selected = []; // 可在此追加分数清零、清除按钮高亮、重置游戏状态逻辑 console.log("游戏已重置,彩色按钮已禁用"); });
额外性能优化建议
你当前sizing.js里用setInterval每0.1毫秒执行一次尺寸计算,会无意义占用大量CPU资源,完全没必要。删掉原有的定时器代码,换成浏览器原生的窗口大小变化监听即可,修改sizing.js末尾部分:
// 删除原有 var refresh = setInterval(...) 代码,替换为以下内容 window.addEventListener('resize', resizing); // 页面初始化时执行一次尺寸适配 resizing();
改完之后只有窗口尺寸实际变化时才会重算元素大小,性能表现会好很多。
内容的提问来源于stack exchange,提问作者Noah Leuthold
相关产品推荐
相关产品推荐

