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

Javascript-添加eventlistener时未定义的数组元素,javascript,jquery,html,arrays,Javascript,Jquery,Html,Arrays,我对javascript相当陌生,我正在尝试获取DOM中的所有“td”元素,并向它们添加一个单击事件。当代码完成执行时,我可以看到cells数组中有37个元素,但当我单击该元素时,无论单击哪个元素,我的console语句中都会出现“clicked td37 undefined”。我不知道哪里出了问题,如果有任何帮助,我将不胜感激 <script> window.addEventListener("DOMContentLoaded", createEventListeners, fal

我对javascript相当陌生,我正在尝试获取DOM中的所有“td”元素,并向它们添加一个单击事件。当代码完成执行时,我可以看到cells数组中有37个元素,但当我单击该元素时,无论单击哪个元素,我的console语句中都会出现“clicked td37 undefined”。我不知道哪里出了问题,如果有任何帮助,我将不胜感激

<script>
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].addEventListener("click", function () {
      console.log("clicked td" +  i + " " + cells[i]);

      }, false);
   }

 }
</script>

addEventListener(“DOMContentLoaded”,createEventListeners,false);
函数createEventListeners(){
var cells=document.getElementsByTagName(“td”);
控制台日志(单元格);
对于(变量i=0;i
在循环结束时,
i
始终是您单击的任何对象的数组长度,由于它们的索引为零,因此不存在具有该索引的元素。例如,如果有10个元素,它们的索引为0-9,但当您单击其中任何一个元素时,
i
始终为10。

在循环结束时,
i
的值将是
单元格。长度
,因此
单元格[i]
未定义。您需要将它们包装在函数中,以便
i
是您想要的值。了解更多关于闭包的信息

函数createEventListeners(){
var cells=document.getElementsByTagName(“td”);
对于(变量i=0;i
这是一个范围问题。您需要一个闭包。在调用循环中的任何
事件
时,
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);
}
var pre=onload;//上一次onload
onload=函数(){
if(pre)pre();
函数createEventListeners(){
var cells=document.getElementsByTagName('td');

对于(var i=0,l=cells.length;i这个问题+答案是何时以及如何使用闭包的一个很好的例子。因为这个问题被标记为
jQuery
,所以
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);
    }
}
window.addEventListener(“DOMContentLoaded”,createEventListeners,false);
函数createEventListeners(){
var cells=document.getElementsByTagName(“td”);
控制台日志(单元格);
对于(变量i=0;i
您需要使用IIFY来隔离作用域,并在函数签名上传递参数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);
    }
}