3

这可能是一个简单的问题,但我无法找出最佳答案。

<div>在屏幕上有 10 个元素。他们每个人都有一个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 。我也不想使用data()jQuery 的方法来存储它。我相信这个问题必须有一个更简单的解决方案,但我找不到它。任何人?

4

3 回答 3

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
}

查看本文中的“臭名昭著的循环”问题(并阅读整篇文章)以获取更多信息:)

于 2012-05-18T16:32:26.310 回答
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 和其他库也会自动处理这些东西。

于 2012-05-18T16:38:25.077 回答
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 );
    }
}​

JsFiddle 在这里

于 2012-05-18T16:39:43.737 回答