This jsfiddle演示了我要实现的目标的基本模型。单击链接后,我应该能够将鼠标悬停在列表元素上,文本应该出现在页面上,但它们没有。当我打印应该出现的字符串的值时,它们是“未定义的”。为什么会这样?
这是下面的 js,但我建议查看 fiddle 。
$('#link1').click(function () {
var foolist = ["foo1", "foo2", "foo3"];
for (var i = 0; i < foolist.length; i++) {
var li = document.createElement('li');
li.innerHTML = "This is a link.";
$(li).hover(function () {
console.log(foolist[i]);
$('#p1').append(foolist[i]);
},
function () {});
$('#ul1').append(li);
}
});
您发现需要一种称为闭包的东西!恭喜 - 没有多少人能看到他们有多酷。这是 pulled from a great MSDN article - 我强烈建议阅读其余部分。
问题是 i
变量不再具有您调用 .hover
时的值 - 如果您记录它,您会看到 i= ==3
。为什么会这样?您传递给 .hover
的函数是一个闭包 - 这意味着它由函数本身和 .click
函数作用域的一种“快照”组成。您在循环的每次迭代中创建一个闭包,但它们都共享相同的“快照”。当您尝试通过点击事件访问 i
时,循环已经完成。
那怎么解决呢?更多关闭!
function showText(i) {
$('#p1').append(foolist[i]);
}
function makeTextCallback(i) {
return function() {
showText(i);
};
}
for (var i = 0; i < foolist.length; i++) {
$(li).hover(makeTextCallback.call(this,i));
}
这被称为“函数工厂”。您将 i
发送到 makeTextCallback
,它在返回的闭包中捕获 i
。
https://jsfiddle.net/aLofhaxp/28/
我是一名优秀的程序员,十分优秀!