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