Javascript - 添加eventlistener时未定义的数组元素

时间:2015-11-20 01:54:35

标签: javascript jquery html arrays

我对javascript很新,我试图抓住DOM中的所有“td”元素并向其添加点击事件。当代码完成执行时,我可以看到我在单元格数组中有37个元素,但是当我单击该元素时,无论点击哪个元素,我都会在控制台语句中“点击td37 undefined”。我不知道什么是错的,任何帮助将不胜感激。

{{1}}

4 个答案:

答案 0 :(得分:3)

在循环结束时,i的值将为cells.length,因此cells[i]未定义。您需要将它们包装在一个函数中,以便i是您想要的值。阅读有关封闭here

的更多信息
function createEventListeners() {
  var cells = document.getElementsByTagName("td");

  for (var i = 0; i < cells.length; i++) {
    (function(i) {
      cells[i].addEventListener("click", function () {
        console.log("clicked td" +  i + " " + cells[i]);
      }, false);
    }(i));
}

答案 1 :(得分:3)

这是一个范围问题。你需要一个关闭。当您的循环中的任何Event被调用时,i会查找它的最后一个已知值,这恰好是它在循环结束时的值。解决方案:

var pre = onload; // previous onload
onload = function(){
  if(pre)pre();
  function createEventListeners(){
    var cells = document.getElementsByTagName('td');
    for(var i=0,l=cells.length; i<l; i++){
      (function(i){
        cells[i].addEventListener('click', function(){
          console.log('i is at position:'+i));
        }, false);
      })(i);
    }
  }
  window.addEventListener('DOMContentLoaded', createEventListeners, false);
}

答案 2 :(得分:0)

在循环结束时,i始终是您点击的任何内容的数组长度,因为它们是零索引,所以不存在具有该索引的元素。例如,如果有10个元素,则它们被编入索引为0-9,但是当您单击其中任何一个元素时,i始终为10。

答案 3 :(得分:0)

这个问题+答案是何时以及如何使用闭包的一个很好的例子。由于此问题标有each,因此jQuery函数可以在each中执行此操作。当您使用$(document).ready(function () { var $tds = $('td'); $tds.each(function (i, td) { $(td).click(function () { console.log(i, td); }); }); }); 时,它可以方便地关闭您正在进行的操作,因此这也可以使用:

i

而且,有一种方法可以在没有闭包的情况下完成。如果通过数据属性将迭代器的值存储到元素本身,它会存储值的副本而不是引用,因此它在分配时保留window.addEventListener("DOMContentLoaded", createEventListeners, false); function createEventListeners() { var cells = document.getElementsByTagName("td"); console.log(cells); for (var i = 0; i < cells.length; i++) { cells[i].setAttribute('data-i', i); cells[i].addEventListener("click", function () { var i = this.getAttribute('data-i'); console.log("clicked td" + i + " " + cells[i]); }, false); } } 的值:

{{1}}