JavaScript闭包。 访问循环到当前i,j变量

我尝试使用jQuery动态生成

,并且我想为每个单元格设置单击处理程序,因此当单击单元格时,弹出窗口将显示当前的单元格索引。 如何在循环中访问CURRENT ij变量?

  for(var i = 0; i < 5; i++) { var tr = $('
'); for (var j = 0; j < 5; j++) { var td = $(''); td.click(function() { alert(i + ' ' + j); // here I want to access to CURRENT i, j variables }) td.appendTo(tr); } }

其他答案主要解释了如何解决闭包问题,尽管这些方法并不特别有效,因为它们最终会为ij每种可能组合创建一个新的闭包。

但是,由于您使用的是jQuery,因此您可以使用许多其他选项:

data参数传递给.on调用

 td.on('click', { i: i, j: j }, function(event) { var i = event.data.i; var j = event.data.j; alert(i + ' ' + j); }); 

您可以在event.data看到上面显示的ij

使用$.each迭代而不是for

 $.each(Array(5), function(i) { // i is already bound here because it's a function parameter $.each(Array(5), function(j) { // and j available here td.on('click', ...); }); }); 

使用事件委派而不是每个元素处理程序

 $('#myTable').on('click', 'td', function() { // use jQuery methods to determine the index, eg var j = this.cellIndex var i = this.parentNode.rowIndex ... }); 

这比单独将一个单独的处理程序绑定到每个

更有效。

更一般地说,使用.data()来存储每个单元格的信息

您可以直接在元素上存储数据值,如果您想要检索单元格和行索引以外的值,这将非常有效:

 td = $('

然后直接从点击的元素的.data提取这些行和列值:

 for (var i = 0; i < 5; i++) { var tr = $('
'); for (var j = 0; j < 5; j++) { $('').data({i: i, j: j}).appendTo(tr); td.appendTo(tr); } } $('#myTable').on('click', 'td', function() { var data = $(this).data(); var i = data.i; var j = data.j; alert(i + ' ' + j); });

将它们引入新范围将捕获它们的当前值:

 (function(i, j) { td.click(function() { alert(i + ' ' + j); // here I want to access to CURRENT i, j variables }); })(i, j); 

您可以通过在循环内执行此类函数来为(i, j)的“当前”值创建新范围

 td.click((function (i, j) { return function (event) { console.log(i, j); } })(i, j)); 

您可以使用Function.prototype.bind使其更简洁

 td.click(function(i, j, event){ console.log(i, j); }.bind(td, i, j)); 

注意.bind解决方案需要ECMAScript 5,因此如果您想支持旧版浏览器,请查看es5-shim


看这个演示

其他选项可以是在元素内存储数据。

  for(var i = 0; i < 5; i++) { var tr = $('
'); for (var j = 0; j < 5; j++) { var td = $(''); this.data("position",{row:i, column:j}); td.click(function() { var position = this.data("position"); alert(position.row + ' ' + position.column); // here I want to access to CURRENT i, j variables }) td.appendTo(tr); } }

我将索引存储为属性并向表中添加单击处理程序:

 var tableHtml = ''; for(var i=0; i<5; i++) { tableHtml += '
'; for (var j=0; j<5; j++) { tableHtml += ''; } tableHtml += ''; } $('table').append(tableHtml).on('click', 'td', function(ev) { var i = this.getAttribute('data-i'), j = this.getAttribute('data-j'); });
').data({i: i, j: j});