JavaScript中如何在for循环内为grid绑定onmousedown右键事件
问题排查与修复方案
你的代码核心存在两个问题:
- 变量作用域问题:使用
var声明的i、j不存在块级作用域,循环结束后所有绑定的事件回调读取到的都是最终的循环终止值,无法匹配你绑定事件时对应的单元格索引 - 事件回调内通过索引查找单元格的写法冗余,且容易受外部变量影响
修复方案
方案1(ES6+ 环境适用,推荐)
将循环变量的声明关键字从var替换为let,利用let的块级作用域特性保留每次循环的独立索引值,同时回调内直接通过事件对象获取当前触发元素,避免依赖外部变量:
document.addEventListener("contextmenu", function (e) { e.preventDefault(); }, false); // var 替换为 let for (let i = Math.max(cellRow - 1, 0); i <= Math.min(cellRow + 1, 9); i++) { for (let j = Math.max(cellCol - 1, 0); j <= Math.min(cellCol + 1, 9); j++) { grid.rows[i].cells[j].onmousedown = function (event) { if (event.which === 3) { // 直接取当前绑定事件的单元格元素 event.currentTarget.innerHTML = "f"; } } } }
方案2(ES5 兼容方案)
如果运行环境不支持ES6语法,可以用立即执行函数创建独立作用域保存每次循环的索引:
document.addEventListener("contextmenu", function (e) { e.preventDefault(); }, false); for (var i = Math.max(cellRow - 1, 0); i <= Math.min(cellRow + 1, 9); i++) { for (var j = Math.max(cellCol - 1, 0); j <= Math.min(cellCol + 1, 9); j++) { // 立即执行函数保存当前i、j的值 (function(curI, curJ) { grid.rows[curI].cells[curJ].onmousedown = function (event) { if (event.which === 3) { this.innerHTML = "f"; } } })(i, j) } }
内容的提问来源于stack exchange,提问作者macuser
相关产品推荐
相关产品推荐

