当我在Google Chrome中运行此示例代码时,不会发生预期的行为 - 在当前页面上的占位符图片代码中加载图片。我在调用showPic()时检查了currPic的值,它是“未定义的”。我知道如果我将showPic的参数从'anchors [i]'改为'this',那么它会起作用,但是试图理解为什么会这样。
function showPic(currPic) {
var srcLoc = currPic.getAttribute("href");
var placeHolder = document.getElementById("placeholder");
placeHolder.setAttribute("src", srcLoc);
var imgLabel = document.getElementById("imglabel");
var currLinkTitle = currPic.getAttribute("title");
imgLabel.firstChild.nodeValue = currLinkTitle;
}
function prepareGallery() {
if(!(document.getElementsByTagName && document.getElementById)) return false;
var imgGallery = document.getElementById("imagegallery");
if(imgGallery) {
var anchors = imgGallery.getElementsByTagName("a");
var i;
for(i = 0; i < anchors.length; i++) {
anchors[i].onclick = function() {
showPic(anchors[i]);
return false;
}
}
}
}
答案 0 :(得分:1)
在匿名函数中,anchors [i]提供运行时引用。点击发生时,anchors[i]
不再存在。虽然它在分配时存在,但它在点击时不属于范围(因为它只是一个数组引用)。但是,使用this
可以提供对单击时始终可用的直接对象的可靠引用。
更简洁地说,anchors[i]
是对数组中位置的引用(一旦for循环退出就会留下范围)。 this
是对dom元素本身的引用。
答案 1 :(得分:0)
因为这也有效:showPic(document.getElementById(anchors[i].id));
- 你现在“得到”它(非常有意思)?
答案 2 :(得分:0)
没有看到关于闭包如何工作的明显陈述,所以这是我对它的看法。
var i;
for(i = 0; i < anchors.length; i++) {
anchors[i].onclick = function() {
showPic(anchors[i]);
return false;
}
}
注意你如何在循环中引用i
变量?在循环结束时,i
的值等于anchors.length
。
因此,当执行onclick
函数的任何时,对i
的引用现在指向一个位置超过anchors
的最后一个索引;这就是为什么您看到currPic
是undefined
。
其他答案中给出了此问题的一种解决方案:使用this
引用当前锚点,不要将anchors[i]
传递给onclick
函数。
由于您可能会遇到类似的情况,我会通过关闭i
的值来向您展示另一种解决方案:
var i;
for(i = 0; i < anchors.length; i++) {
anchors[i].onclick = (function(i) {
// inside this function, i is closed over and won't change anymore
return function() {
showPic(anchors[i]);
return false;
}
}(i));
}