动态绑定addEventListener时所有元素均传入最后一个props值的问题
解决循环绑定点击事件时始终获取最后一个元素属性的问题
你遇到的是闭包作用域陷阱:用var声明的elem属于函数级作用域,在整个循环过程中共享同一个引用。当点击事件触发时,循环已经执行完毕,elem已经指向数组的最后一个元素,所以所有事件回调都会拿到最后一个元素的props值。
解决方案1:用let替换var声明循环变量
let是块级作用域,每次循环都会创建一个新的elem绑定,确保每个事件回调捕获的是当前迭代的元素:
for(let elem of taggedElements){ let el = document.querySelector(elem.cssSelector); if(el){ el.addEventListener("click", function(){ logCustomEvent(elem.props) }); } }
解决方案2:使用立即执行函数表达式(IIFE)封装作用域
如果需要兼容不支持ES6的旧浏览器,用IIFE把当前迭代的元素封装到独立作用域中:
for(var elem of taggedElements){ let el = document.querySelector(elem.cssSelector); if(el){ (function(currentElem) { el.addEventListener("click", function(){ logCustomEvent(currentElem.props) }); })(elem); } }
解决方案3:改用forEach遍历数组
forEach的回调函数自带独立作用域,每个迭代的元素都是独立的引用:
taggedElements.forEach(function(elem) { let el = document.querySelector(elem.cssSelector); if(el){ el.addEventListener("click", function(){ logCustomEvent(elem.props) }); } });
以上三种方法都能解决问题,核心是让每个事件回调都能捕获到当前迭代元素的独立引用,而不是共享的循环变量。
内容的提问来源于stack exchange,提问作者user1735894
相关产品推荐
相关产品推荐

