我有一个带有1,2,3,4按钮的幻灯片。我还定义了一个带有4个图像网址的数组。单击该按钮时,它将调用特定的相应URL。
<div id="slideshow">
<div id="source"><img src="images/blue.jpg">
<ul id="controller">
<li class="button">1</li>
<li class="button">2</li>
<li class="button">3</li>
<li class="button">4</li>
</ul>
</div>
</div>
使用Javascript:
var button=document.getElementsByClassName("button")
var image=document.getElementsByTagName("img")[0]
var sources=new Array("images/blue.jpg","images/red.jpg","images/yellow.jpg","images/green.jpg");
for (var i=0;i<sources.length;i++){
button[i].onclick=function(){
image.src=sources[i]
}
}
但是当我点击按钮时,来源[i]总是返回undefined。
答案 0 :(得分:0)
for (var i=0;i<sources.length;i++){
button[i].onclick= function(i){
return function(){
image.src=sources[i]
}
}(i);
}
试试这个http://jsbin.com/puyipiro/1/
P.S。 onclick处理程序中的错误原因i等于4,因此必须使用创建处理程序
在每次迭代时保存当前值答案 1 :(得分:0)
您遇到了JavaScript中最令人困惑的部分之一,即闭包捕获问题。要让你的代码重新编写,
var button=document.getElementsByClassName("button")
var image=document.getElementsByTagName("img")[0]
var sources=new Array("images/blue.jpg","images/red.jpg","images/yellow.jpg","images/green.jpg");
for (var i=0;i<sources.length;i++){
(function (i) {
button[i].onclick=function(){
image.src=sources[i]
}
})(i);
}
这使用一个立即执行的函数来引入一个新的范围,因此每个onclick
都有自己的i
副本,在创建函数时它的值为i
而不是共享相同的i
,其值为sources.length
。
如果您定位支持ES 6的浏览器,则可以使用let
代替var
,然后允许您将其写为,
var button=document.getElementsByClassName("button")
var image=document.getElementsByTagName("img")[0]
var sources=new Array("images/blue.jpg","images/red.jpg","images/yellow.jpg","images/green.jpg");
for (var i=0;i<sources.length;i++){
let j = i;
button[i].onclick=function() {
image.src=sources[j]
}
}
let
语句为循环中的每次迭代为j
创建一个新的范围,因此j
函数捕获的onclick
不同并存储{的值{1}}当函数被创建为上面立即执行的函数时。
不幸的是,ES 6尚未广泛使用,因此我原始建议的一些变体就是您所需要的。
答案 2 :(得分:-1)
您可以将i
值存储在适当的DOM元素(按钮)中,例如作为属性,然后在onclick
处理程序中检索它们。不知怎的,这样:
for (var i=0;i<sources.length;i++){
button[i].setAttribute('data-btn_i', i);
button[i].onclick=function(){
image.src=sources[this.getAttribute('data-btn_i')];
}
}