动态创建元素并添加onclick事件不起作用

5

我有一个for循环,它创建带有ID的

元素,例如'category1'、'category2'等。该循环遍历一个键/值数组,该数组看起来像这样:

"0" : "Java",
"1" : "JavaScript",
"2" : "HTML"

因此,div的ID为“category” +键。

在将元素添加到容器div的innerHTML中的for循环中,我添加了一个onclick事件。

这就是我所说的for循环:

for (var key in categories) {
    categoriesBlock.innerHTML += '<div class="category" id="category' + key + '">' + categories[key] + '</div>';

    document.getElementById('category' + key).onclick = function() { showPostsForCategory(key, categories[key]); }
}

其中categories是上述数组。

问题在于,onclick仅适用于数组中的最后一个元素。如果我使用Safari调试器并输入“category3.onclick”,它会显示null。如果我输入“category4.onclick”(即最后一个元素),它会返回正确的函数。

这是怎么可能的?如何解决?


调试工具中呈现的HTML长什么样? - Dragony
就像你从代码中所期望的那样,这只是普通的div。 - Jeroen
1个回答

3

这是一个作用域问题。点击处理程序指向最后的值,因为它在循环结束时变成了那个值。以下是一种捕获该值的方法。

for (var key in categories) {        
    (function(){
      var _key = key;
      document.getElementById('category' + _key).onclick = function() { showPostsForCategory(_key, categories[_key]); }
    })();
}

此外,字符串拼接不是创建HTML元素的理想方式。在某些浏览器中,插入文本后变成实际的HTML元素之间可能会有延迟。

var div = document.createElement('div');
div.onclick = function(){...};
categoriesBlock.appendChild(div);

这不起作用。它只给出相同的结果:只有最后一个具有onclick事件。非常奇怪。你还有其他想法吗? - Jeroen
终于成功了!我将您的初始答案(_key和嵌套函数)与您的编辑答案结合起来。现在它可以工作了。这并不是很有意义,特别是因为我以前没有真正使用过JavaScript。无论如何,谢谢! - Jeroen

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接