使用bind为事件监听器的命名回调传递参数失效问题求助
问题根因
- 你调用
bind生成了绑定额外参数的新函数,但实际调用addEventListener时仍然绑定的是原回调函数,参数绑定逻辑完全没有生效 - 仅用单个全局变量存储绑定后的函数,遍历多元素时会反复覆盖变量值,无法为每个元素保留对应的绑定函数用于后续移除
bind传入的参数会排在函数执行时接收参数的最前列,原clearText的参数顺序不匹配:如果绑定逻辑生效,你通过bind传入的额外参数会被赋值给第一个形参e,浏览器传入的事件对象反而会被赋值给第二个形参text,最终也拿不到预期值
修正方案
使用WeakMap存储每个元素对应的绑定后回调函数,既不会污染DOM元素,也支持自动垃圾回收,调整后的代码如下:
// adminView.js // 存储元素和对应绑定后回调的映射关系 const boundFocusHandlers = new WeakMap(); export const addFocusInListeners = (items, cb) => { items.forEach(item => { // 绑定this指向当前元素,传入额外参数 const boundHandler = cb.bind(item, 'extra argument'); // 存储绑定后的函数用于后续移除 boundFocusHandlers.set(item, boundHandler); // 绑定生成的新函数,而非原回调 item.addEventListener('focusin', boundHandler); }); }; export const removeFocusInListeners = (items) => { items.forEach(item => { const boundHandler = boundFocusHandlers.get(item); if (boundHandler) { item.removeEventListener('focusin', boundHandler); boundFocusHandlers.delete(item); } }); } // 调整参数顺序:第一位是bind传入的额外参数,第二位是事件对象 export const clearText = (text, e) => { console.log(e.currentTarget); console.log(e.target); console.log(text); // 正常打印 'extra argument' console.log(this); // 指向当前绑定的元素 };
调用移除监听器方法时直接传入元素数组即可:
adminView.removeFocusInListeners(arrayOfElements);
内容的提问来源于stack exchange,提问作者NickW
相关产品推荐
相关产品推荐

