JavaScript点击子元素时获取对应索引报错如何解决
报错原因
document.querySelectorAll() 返回值是 NodeList 类数组结构,并非标准数组对象,本身不提供数组原型上的indexOf()方法,直接调用就会触发报错,导致功能失效。
可直接运行的修复方案
方案1:直接利用forEach回调自带的索引参数(最简便)
forEach遍历NodeList时,回调函数的第二个入参就是当前遍历元素的索引,直接在点击事件的闭包中读取即可,不需要额外调用方法查找索引:
let parent = document.querySelector('.parent'); let children = document.querySelectorAll('.child'); // forEach回调第二个参数就是当前元素的索引 children.forEach((child, index) => { child.onclick = function () { console.log(index); } });
方案2:转成真实数组后使用indexOf
如果确实想通过indexOf查找索引,先把NodeList转为标准数组即可,支持Array.from()或者展开运算符两种写法:
let parent = document.querySelector('.parent'); // 转成真正的数组 let children = Array.from(document.querySelectorAll('.child')); // 也可以写为 let children = [...document.querySelectorAll('.child')]; children.forEach(child => { child.onclick = function () { console.log(children.indexOf(child)); } });
方案3:事件委托实现(性能更优,适合动态增减子元素的场景)
不需要给每个子元素单独绑定事件,只需要给父容器绑定一次点击事件,通过事件对象判断点击目标,再查索引即可,后续新增的.child元素也能自动生效:
let parent = document.querySelector('.parent'); parent.onclick = function(e) { // 判断点击目标是child元素才触发逻辑 if(e.target.classList.contains('child')){ // 把父元素的子元素集合转成数组,查找当前点击目标的索引 let index = Array.from(parent.children).indexOf(e.target); console.log(index); } }
以上方案都可以搭配原有HTML结构直接运行:
<div class="parent"> <div class="child">a</div> <div class="child">b</div> <div class="child">c</div> <div class="child">d</div> </div>
内容的提问来源于stack exchange,提问作者Mr-montasir
相关产品推荐
相关产品推荐

