日常-js原生for循环绑定事件时,引用循环里的变量,发现只是最后值的问题

疑惑:for循环绑定事件,事件内部引用循环里的变量,发现只会得到最后值,而不是循环到的每一个值。

回答:在javascript中,没有块级作用域,只有函数作用域,也就是说在执行一个函数的时候会新开辟内存空间,click方法必须要点击的时候才能会调用,但是for循环已经执行完毕,i等于最后一个值,所以当点击的时候总是最后一个。

云南之旅相册:
window.onload=function(){ //页面加载后再执行
var as=document.querySelectorAll("a"),
    imgs=document.querySelectorAll("img");
for (var i = as.length - 1; i >= 0; i--) {//外循环
  // console.log(i);//5 4 3 2 1 0
  // console.log(this);//this指向window对象
  as[i].onclick=function(){
  // console.log(i);//点击之后打印-1,i是外部for循环完成之后的最终结果-1
    for (var j = imgs.length - 1; j >= 0; j--) {
    imgs[j].style.opacity='0';
    // return;不能return,会影响停止后面的操作
    // console.log(this);this指向当前被绑定事件的对象
    // console.log(i);//点击之后打印一堆-1,i是外部for循环完成之后的最终结果-1
   }
    imgs[i].style.opacity='1';//报错,i不可用
     }
 }
};

解决方法1:利用call方法借用数组的indexOf方法,得到触发事件元素的index值

   imgs[[].indexOf.call(as,this)].style.opacity='1';
   //利用call方法借用数组的内置对象indexOf方法,将as替换原空数组,传入this查找并返回索引

解决方法2:保存外层函数的执行作用域,也就是用闭包来解决。

for (var i = as.length - 1; i >= 0; i--) {
	(function(k) {
		as[k].onclick=function(){
			console.log(i);
			for (var j = imgs.length - 1; j >= 0; j--) {
				imgs[j].style.opacity='0';
			}
		imgs[k].style.opacity='1';
		}
	})(i);//以i为参数传给k函数自调用
 }
//闭包的作用是把定义的变量保存到内存中,不被销毁,这里是就每次穿过来的i都被k接受并且保存。

闭包还有其他写法,如(funciton()()) !function()() ~function()() 等等

方法3:元素添加一个index属性保存你要用的值,然后直接从属性中取得。

for (var i = as.length - 1; i >= 0; i--) {	
	as[i].index=i;
	as[i].onclick=function(){
		for (var j = imgs.length - 1; j >= 0; j--) {
	        imgs[j].style.opacity='0';
		}
	imgs[this.index].style.opacity='1';
	}
}

方法4:利用ES6中典型的let块级作用域。


for (let i = as.length - 1; i >= 0; i--) {
  as[i].onclick=function(){
   console.log(i);
   for (var j = imgs.length - 1; j >= 0; j--) {
    imgs[j].style.opacity='0';
   }
  imgs[k].style.opacity='1';
  }
 }
}//ES6中,for中的{}也属于块级作用域。

成了!

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值