共计 1468 个字符,预计需要花费 4 分钟才能阅读完成。
希望可以实现点击哪个就打印出对应的顺序
<ul>
<li> 第 0 个 </li>
<li> 第 1 个 </li>
<li> 第 2 个 </li>
<li> 第 3 个 </li>
<li> 第 4 个 </li>
</ul>
错误实现:
注意此处使用的 var i=0, var 是可以被重复定义的,最后执行了 i ++,根据垃圾回收机制,当点击事件发生的时候,i 已经变成 5 了,所以不管点击哪个 li,打印的都是 5
window.onload=()=>{const list = document.querySelectorAll('li')
for (var i=0; i<list.length; i++){list[i].onclick = ()=>{console.log(i)
}
}
}
正确实现:
方法一:给每个 li 添加自定义属性
window.onload=()=>{const list = document.querySelectorAll('li')
for (var i=0; i<list.length; i++){list[i].index = i
list[i].onclick = function (){console.log(this.index)
}
}
}
方法二:自执行函数,并利用作用域的关系,定义函数把 i 传进来,并进行自动调用
for (var i=0; i<list.length; i++){// (function(i){}) 表示定义,i 表示形参;(i) 表示调用,i 表示实参
(function(i){list[i].onclick = function(){console.log(i)
}
})(i)
}
方法三:ES6 中的 let,let 应用于块级作用域,块级作用域以大括号划分
let 不会被垃圾回收机制回收,var 为什么会被回收?因为 var 声明的变量会被覆盖,而 let 不能被覆盖,就会被存下来。
for (let i=0; i<list.length; i++){list[i].onclick = ()=>{console.log(i)
}
}
方法四:利用 for 循环的方法:filter、forEach、map(注意全都是 ES5 的,不是 ES6 的)
// 注意此处有一个兼容性问题,li 是类数组,兼容性好的浏览器可以直接使用这三个方法,但是兼容性不好的不能直接用
// 为保证稳妥,最好转成真正的数组
const newArr = [].slice.call(list) // 或者 const newArr = Array.prototype.slice.call(list), [] 是 Array 的原型
console.log(list) // NodeList(5) [li, li, li, li, li] NodeList 是 dom 中的一个对象
console.log(newArr) // [li, li, li, li, li] 被转成了真正的数组
newArr.forEach((value,index)=>{value.onclick=function(){console.log(index)
}
})
newArr.filter((value,index)=>{value.onclick=function(){console.log(index)
}
})
newArr.map((value,index)=>{value.onclick=function(){console.log(index)
}
})
方法五:ES6 中给 Array 的 from 方法
Array.from(list, function(value, index){value.onclick=function(){console.log(index)
}
})
正文完
发表至: javascript
2019-08-08