背景
有一个需求:为表格的每一行绑定一个mouseover事件。很简单的样子,只需遍历所有tr,为每个tr绑定mouseover事件即可。代码如下:
var trs = $("table").find("tr");
for (var i=0; i<trs.length; i++) {
$(trs[i]).bind("mouseover", function() {
$(trs[i]).css("background"), "yellow");
});
}
问题出现了,事件绑定无效,于是我就用顺序语句写。
var trs = $("table").find("tr");
$(trs[0]).bind("mouseover", function() {
$(trs[0]).css("background"), "yellow");
});
$(trs[1]).bind("mouseover", function() {
$(trs[1]).css("background"), "yellow");
});
$(trs[2]).bind("mouseover", function() {
$(trs[2]).css("background"), "yellow");
});
竟然成功了,不可思议,难道我碰到假的for语句?于是赶紧百度压压惊。百度说:用闭包可以解决。
原因
事件什么时候触发?很明显要你做出相应动作才执行。for循环在你动作触发之前已经结束了,所以循环变量i就变成了trs.length,数组都溢出了怎么可能绑定事件成功。
解决
用一个函数把事件执行代码包起来,确保每次循环执行时,都能执行函数的内容。
var trs = $("table").find("tr");
for (var i=0; i<trs.length; i++) {
(function(i) {
$(trs[i]).bind("mouseover", function() {
$(trs[i]).css("background"), "yellow");
});
})(i);
}
当然,还有其他解决方法,万能的百度、谷歌。