0

我尝试<table>使用 jQuery 动态生成,并且我想为每个单元格设置单击处理程序,因此当单击单元格时,弹出窗口将显示当前单元格索引。如何在循环中访问 CURRENTij变量?

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

5 回答 5

2

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

(function(i, j) {
    td.click(function() {
        alert(i + ' ' + j);  // here I want to access to CURRENT i, j variables
    });
})(i, j);
于 2013-09-01T17:00:54.240 回答
2

(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


看这个演示

于 2013-09-01T17:06:52.110 回答
2

其他答案主要解释了如何解决闭包问题,尽管此类方法的内存效率不是特别高,因为它们最终会为i和的每个可能组合创建一个新的闭包j

但是,由于您使用的是 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);
});

如您在上面看到的,ij值将在event.data

用于$.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, e.g.
    var j = this.cellIndex
    var i = this.parentNode.rowIndex
    ...
});

这比将单独的处理程序单独绑定到每个处理程序更有效<td>

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

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

td = $('<td>').data({i: i, j: j});

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

for (var i = 0; i < 5; i++) {
    var tr = $('<tr></tr>');
    for (var j = 0; j < 5; j++) {
        $('<td></td>').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);
});
于 2013-09-01T17:28:49.017 回答
0

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

  for(var i = 0; i < 5; i++)
  {
      var tr = $('<tr></tr>');
      for (var j = 0; j < 5; j++) 
      {
          var td = $('<td></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);
      }
  } 
于 2013-09-01T17:21:02.110 回答
0

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

var tableHtml = '';

for(var i=0; i<5; i++) {
    tableHtml += '<tr>';

    for (var j=0; j<5; j++) {
        tableHtml += '<td data-i="' + i + '" data-j="' + j + '"></td>';
    }

    tableHtml += '</tr>';
}

$('table').append(tableHtml).on('click', 'td', function(ev) {
    var i = this.getAttribute('data-i'),
        j = this.getAttribute('data-j');
});
于 2013-09-01T17:23:51.197 回答