相比很多人都遇见过这样的情况: 给一个ul的所有li绑定行为,在点击时获取其index。
假设结构如下:
<body> <ul> <li>0</li> <li>1</li> <li>2</li> <li>3</li> <li>4</li> <li>5</li> </ul> </body>
很多人会这么做:
var list= document.querySelectorAll('ul li') for(var i= 0; i< list.length; i ++){ list[i].addEventListener('click', function(){ console.log(i) }) }
结果输出的全是5,这便是闭包的最常见的出现情形。
解决方案:
1.利用let块级作用域的特性
var list= document.querySelectorAll('ul li') for(let i= 0; i< list.length; i ++){ list[i].addEventListener('click', function(){ console.log(i) }) }
2.利用自执行函数独立作用域,也是红宝书里推荐的写法
var list= document.querySelectorAll('ul li') for(var i= 0; i< list.length; i ++){ (function(i){ list[i].addEventListener('click', function(){ console.log(i) }) }(i)) }
3.利用事件委托机制(只适用于li内没有其余元素的情况)
var list= document.querySelector('ul')
list.onclick= function(e){
var e= window.event||e
var target= e.target||e.srcElement
if(target.nodeName.toLowerCase()== 'li'){
console.log([].indexOf.call(document.querySelectorAll('li'), target))
}
}