循环内事件监听函数无法访问变量i的技术咨询
循环绑定点击事件时无法访问循环变量的解决办法
你的代码问题出在循环变量i的作用域和异步事件触发时机上:
- 你没给i加
let/const声明,默认是全局变量,整个循环共用同一个i - 点击事件是异步触发的,等用户点击时循环已经跑完,i的值变成了
headers.length,这时候bodies[i]根本找不到对应元素
另外注意你代码里的拼写错误:heigth要改成height才生效。
下面是几种可行的解决方法:
方法1:用let声明循环变量(最简单)
let有块级作用域,每次循环都会生成一个独立的i绑定,事件回调能捕获到当前循环的i值:
const headers = document.getElementsByClassName('header'); const bodies = document.getElementsByClassName('body'); for (let i = 0; i < headers.length; i++) { headers[i].addEventListener('click', () => { bodies[i].style.height = 0; }) };
方法2:用闭包保存循环变量
通过立即执行函数创建独立作用域,把当前循环的i作为参数传进去:
const headers = document.getElementsByClassName('header'); const bodies = document.getElementsByClassName('body'); for (var i = 0; i < headers.length; i++) { (function(index) { headers[index].addEventListener('click', () => { bodies[index].style.height = 0; }) })(i); };
方法3:用forEach遍历(更清晰)
把HTMLCollection转成数组后用forEach遍历,回调函数自带的索引会保留当前值:
const headers = Array.from(document.getElementsByClassName('header')); const bodies = Array.from(document.getElementsByClassName('body')); headers.forEach((header, index) => { header.addEventListener('click', () => { bodies[index].style.height = 0; }); });
内容的提问来源于stack exchange,提问作者Ateix
相关产品推荐
相关产品推荐

