这可能是一个简单的问题,但我无法找到最佳答案。
屏幕上有10个<div>
元素。他们每个人都有一个click()
事件监听器:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
</head>
<body>
<div id="element0">Click me! (0)</div>
<div id="element1">Click me! (1)</div>
<div id="element2">Click me! (2)</div>
<div id="element3">Click me! (3)</div>
<div id="element4">Click me! (4)</div>
<div id="element5">Click me! (5)</div>
<div id="element6">Click me! (6)</div>
<div id="element7">Click me! (7)</div>
<div id="element8">Click me! (8)</div>
<div id="element9">Click me! (9)</div>
<script type="text/javascript">
for ( var i = 0; i < 10; i++ ) {
var element = document.getElementById( "element" + i );
element.onclick = function () {
alert( "Element " + i );
}
}
</script>
</body>
</html>
但每次点击一个元素时,它都会显示“元素10”!似乎所有这些事件处理程序都使用i
的相同值。
我希望它显示“元素N”,其中N是当前元素的编号。我不想从元素id中提取N.我不想使用jQuery的data()
方法存储它。我相信这个问题必须有一个更简单的解决方案,但我找不到它。任何人吗?
答案 0 :(得分:6)
您的所有点击处理程序共享的外部作用域中只有一个变量i
。您需要为每个闭包创建一个局部变量i
。这将有效:
for ( var i = 0; i < 10; i++ ) {
var element = document.getElementById( "element" + i );
element.onclick = (function(i){
// returns a new function to be used as an onclick handler
return function () {
alert( "Element " + i );
}
})(i); // Pass in the value of the outer scope i
}
查看this article中的“臭名昭着的循环”问题(并阅读整篇文章)以获取更多信息:)
答案 1 :(得分:3)
所以你的问题就是在循环中做异步代码的本质,就像其他帖子所说的那样。在你的情况下,尽管有一个更好的方法来解决这个问题,并且正在使用事件委托。
document.body.onclick = function(e) {
if (e.target.tagName.toLowerCase() === "div") {
alert( "Element " + e.target.id );
}
}
如果你有jQuery,你可以这样做:
$(document.body).on("click", "div", function() {
alert($(this).attr("id"));
});
有关详细信息,请查看此文章: http://www.sitepoint.com/javascript-event-delegation-is-easier-than-you-think/
显然,jQuery和其他libs也会自动处理这些内容。
答案 2 :(得分:2)
您可以从元素的id
属性中获取数字:
for ( var i = 0; i < 10; i++ ) {
var element = document.getElementById( "element" + i );
element.onclick = function () {
var i = this.id.substr(7);
alert( "Element " + i );
}
}