循环生成表格输入框时onchange事件无法获取对应输入框唯一ID的问题
循环生成表格输入框时onchange事件无法获取对应输入框唯一ID的问题
兄弟,你碰到的这个问题是典型的闭包作用域陷阱,我来给你理清楚原因和解决办法:
问题根源
你在循环里给每个input绑定的onchange函数,引用的是循环作用域里的thisInputID变量。但循环是同步执行的,等用户触发onchange事件时,循环早就跑完了,thisInputID已经被更新成最后一次循环的值,所以所有输入框的事件都会弹出同一个ID。
三种解决办法
1. 利用事件对象直接获取当前输入框的ID(最推荐)
既然你已经给每个input设置了唯一的id属性,那完全可以在事件函数里直接通过触发事件的元素拿到ID,根本不需要额外保存thisInputID:
input.onchange = function(event) { // 两种方式都能拿到当前输入框的ID alert(this.id); // 或者 alert(event.target.id); };
这种方法最直观,也避开了闭包的坑,是最优解。
2. 用ES6的let创建块级作用域
如果你的运行环境支持ES6,可以把thisInputID的声明放到循环内部,let的块级作用域特性会让每次循环都生成一个独立的变量绑定,事件函数能正确捕获当前循环的ID:
// 假设你的循环结构类似这样 for (let i = 0; i < yourLoopLength; i++) { let thisInputID = `unique-input-${i}`; // 用let在循环内声明 // 创建input的代码... input.id = thisInputID; input.onchange = function() { alert(thisInputID); }; // 把input插入到单元格... }
3. 立即执行函数(IIFE)创建独立作用域(兼容旧环境)
如果需要兼容不支持ES6的环境,可以用立即执行函数把当前的thisInputID封装起来,让每个事件函数绑定自己专属的ID值:
input.onchange = (function(currentID) { return function() { alert(currentID); }; })(thisInputID);
每次循环时,立即执行函数会把当前的thisInputID作为参数传入,返回的内部函数会引用这个独立作用域里的currentID,不会被后续循环覆盖。
备注:内容来源于stack exchange,提问作者Schwarz Software
相关产品推荐
相关产品推荐

