Javascript 添加';单击';循环中的事件侦听器

Javascript 添加';单击';循环中的事件侦听器,javascript,events,loops,click,listeners,Javascript,Events,Loops,Click,Listeners,重构html标记中的标准onClick,侦听器面临代码问题: var td; for (var t=1;t<8;t++){ td = document.getElementById('td'+t); if (typeof window.addEventListener==='function'){ td.addEventListener('click',function(){ c

重构html标记中的标准
onClick
,侦听器面临代码问题:

var td;
    for (var t=1;t<8;t++){
        td = document.getElementById('td'+t);
        if (typeof window.addEventListener==='function'){
                td.addEventListener('click',function(){
                    console.log(td);
            })}
 }  
var-td;

for(var t=1;t据我所知,它是由于闭包而发生的…您在for语句的范围内分配事件处理程序。单击“发生”时,它会获取for范围内的最后一个版本if TD变量并将其写入日志。

您需要将事件侦听器的分配包装在闭包中,类似于:

var td;
for (var t = 1; t < 8; t++){
    td = document.getElementById('td'+t);
    if (typeof window.addEventListener === 'function'){
        (function (_td) {
            td.addEventListener('click', function(){
                console.log(_td);
            });
        })(td);
    }
}
var-td;
对于(var t=1;t<8;t++){
td=document.getElementById('td'+t);
if(typeof window.addEventListener==='function'){
(功能){
td.addEventListener('click',function(){
console.log(_td);
});
})(td);
}
}

以下各项应按预期工作:

  for (var t=1;t<8;t++){
        var td;
        td = document.getElementById('td'+t);
        if (typeof window.addEventListener==='function'){
                td.addEventListener('click',function(){
                    console.log(this);
            })}
 } 

用于(var t=1;t因此,这里发生的事情是,您将变量“td”保留在事件侦听器函数的作用域中。只有一个“td”实例,并且每次for循环迭代时都会更新它。因此,当for循环完成时,td的值现在设置为元素“#td7”,并且您的事件处理程序只是记录cutd的当前值

在上面的示例中,您可以简单地记录“this”:

var td;
for (var t=1;t<8;t++){
    td = document.getElementById('td'+t);
    if (typeof window.addEventListener==='function'){
      td.addEventListener('click',function(){
        console.log(this);
      });
    }
}
var-td;
对于(var t=1;t发生了什么
变量
td
是在事件处理程序之外定义的,因此,当您单击单元格时,您将记录其上次设置的值

更严格地说:每个事件处理程序函数都是一个闭包——一个引用外部范围变量的函数

通解 此类问题的一般解决方案是从包装函数返回事件处理程序,并将要“修复”的变量作为参数传递:

td.addEventListener('click',函数(wrapTD){
返回函数(){console.log(wrapTD);}
}(td);;
参数现在绑定到被调用的包装器函数的作用域

更简单的解决方案:使用
但是,还有一个更简单的选项。在事件处理程序中,
设置为定义处理程序的元素,因此您可以使用
而不是
td

td.addEventListener('click',function(){
console.log(this);
});
更简单的是:没有循环! 最后,您可以完全摆脱
for
循环,并在整个表上设置单个事件处理程序:

var table=document.getElementById('my-table');
表.addEventListener('click',函数(e){
if(e.target.nodeName.toUpperCase()!=“TD”)返回;
var td=e.target;
console.log(td);
});

对于较大的表,这是一个更好的解决方案,因为您将用一个事件处理程序替换多个事件处理程序。请注意,如果您将文本包装在另一个元素中,则需要调整此设置,以检查目标元素是否是
td

的后代。您可以尝试在循环内声明
var
,或者明确地尝试相同的代码吗对于td1 after循环。听起来很愚蠢,让我们试试。@Azodious,是的,已经尝试过了,结果是sameif显式指定(硬代码),例如,
td1
它可以工作,可以尝试创建长度为8的数组。用
td
对象填充它,然后尝试将侦听器附加到索引。也许是这样。但我预计每个td:td1、td2、…td8都会被填充,可以工作。谢谢。关于闭包的更多问题:
\u td
等于
td
?闭包只是一个立即执行的函数,因此在执行时保留变量的状态。我们通过将
td
\u td
输入参数传递给函数来执行函数/闭包。感谢您的解释。我只是混淆了
\u td
td
naming.看起来,我可以使用
td
是的,如果能得到一些关于td是什么以及td是什么的解释,那就太好了最后是。@Hermanningjaldson np,
\u td
只是构成闭包的
函数的输入参数,
td
最后是传递给
函数的值。它们实际上不必有不同的名称,例如,它们都可以是
td
。希望有帮助:-)很好的解决方案,一切正常
for (var t=1;t<8;t++){
  bind_event(t);
}

function bind_event(t) {
    var td = document.getElementById('td'+t);
    if (typeof window.addEventListener==='function'){
      td.addEventListener('click',function(){
        console.log(td);
      });
    }
}