我的问题是关于此页面上的示例:http://api.jquery.com/event.data/
<button> 0 </button>
<button> 1 </button>
<button> 2 </button>
<button> 3 </button>
<button> 4 </button>
<div id="log"></div>
JS:
var logDiv = $( "#log" );
for ( var i = 0; i < 5; i++ ) {
$( "button" ).eq( i ).on( "click", { value: i }, function( event ) {
var msgs = [
"button = " + $( this ).index(),
"event.data.value = " + event.data.value,
"i = " + i
];
logDiv.append( msgs.join( ", " ) + "<br>" );
});
}
在此演示中,当我单击其中一个按钮时,输出如下所示:
button = 0,event.data.value = 0,i = 5
我不明白的是为什么&#34; i = 5&#34;在这里,不应该&#34;我&#34;等于&#34; 0&#34;在这种情况下?
答案 0 :(得分:1)
这是因为当您i
时引用的"i = " + i
是相同的 i
,for
在{{1}中递增循环。
当循环结束,并且当您的点击事件最终被触发时,i
将增加到5.当您将其作为event.data
传递时,您将&#34;捕获&#34;当前值,这就是你获得0的原因。
答案 1 :(得分:0)
这就是重点。运行代码时,会设置五个不同的事件处理程序。这是JS引擎的第一个事件处理程序的样子:
$("button").eq(0).on("click", {value: 0}, function(event) { /* i set to zero */
var msgs = [
"button = " + $(this).index(),
"event.data.value = " + event.data.value, /* passed in via {value: 0} */
"i = " + i /* i remains a variable inside the callback function */
];
logDiv.append( msgs.join( ", " ) + "<br>" );
});
请注意,i
在回调函数中不能设置为零;它仍然是一个变量。在调用事件处理程序时(单击按钮时),for
循环已完成,i=5
。
要做你想象应该发生的事情,我们需要将循环内部包裹在closure中:
for (var i = 0; i < 5; i++) {
(function (i) { /* start of closure */
$("button").eq(i).on("click", function (event) {
var msgs = [
"button = " + $(this).index(),
"i = " + i];
logDiv.append(msgs.join(", ") + "<br>");
});
})(i); /* end of closure */
}
http://jsfiddle.net/mblase75/qeXn5/
...或者只使用event.data.value
代替i
。
答案 2 :(得分:0)
事件监听器持有对&#34; i&#34;的引用。变量,用于for语句。在for循环结束后,该值将为5,并且所有&#34; click&#34;正在添加监听器:它是在&#34; i ++&#34;中设置的最新值。在条件失败之前&#34; i&lt; 5&#34;