能否无需传入event对象即可在equalizer函数中访问它?
如何在节流后的equalizer函数中无需传入event对象就能访问它?
我编写了一个equalizer函数,使用lodash的throttle方法,在窗口resize和load时执行,用于为指定元素设置相同的minHeight。目前每次调用该函数都必须传入event对象,因为需要通过e.type === 'resize'来做逻辑判断。原以为借助闭包特性,函数可以直接访问外部变量,无需传入event对象,请问是否存在无需每次传入event对象,就能在equalizer函数中访问它的方法?
相关代码如下:
export const equalizer = throttle((elems, e, stopAt = 0) => { const elements = [...document.querySelectorAll(elems)]; const setMinHeight = (el) => el.style.minHeight = '0px'; if (e.type === 'resize') elements.forEach(setMinHeight); const minHeight = elements.reduce((acc, cur) => { if (cur.clientHeight >= acc) return cur.clientHeight; if (acc >= cur.clientHeight) return acc; }, 0); elements.forEach((el) => (el.style.minHeight = `${minHeight}px`)); }, 500);
调用代码:
['load', 'resize'].forEach((event) => { window.addEventListener(event, function (e) { equalizer('.comment__body p', e); equalizer('.comment__header .comment__name', e); }); });
解决方案:用工厂函数封装,通过闭包保存元素选择器,让函数直接接收event
核心思路是把元素选择器和stopAt参数通过闭包提前绑定,让最终生成的节流函数直接接收事件对象(事件监听时浏览器会自动传入),无需手动传递。同时这种方式还能为每个选择器创建独立的节流实例,避免共享节流状态导致的逻辑异常。
1. 重构equalizer为工厂函数
import { throttle } from 'lodash'; export const createEqualizer = (elems, stopAt = 0) => { // 返回绑定了选择器的节流处理函数,直接接收event参数 return throttle((e) => { const elements = [...document.querySelectorAll(elems)]; const setMinHeight = (el) => el.style.minHeight = '0px'; if (e.type === 'resize') elements.forEach(setMinHeight); // 简化reduce逻辑,用Math.max更简洁 const minHeight = elements.reduce((acc, cur) => Math.max(acc, cur.clientHeight), 0); elements.forEach((el) => (el.style.minHeight = `${minHeight}px`)); }, 500); };
2. 优化调用方式
// 为每个需要等高的元素组创建独立的节流处理函数 const equalizeCommentBody = createEqualizer('.comment__body p'); const equalizeCommentName = createEqualizer('.comment__header .comment__name'); // 直接绑定到事件监听,无需手动传event ['load', 'resize'].forEach((event) => { window.addEventListener(event, equalizeCommentBody); window.addEventListener(event, equalizeCommentName); });
逻辑说明
- 工厂函数
createEqualizer接收参数后,返回的节流处理函数通过闭包可以访问到elems和stopAt,无需每次调用时传入。 - 事件触发时,浏览器会自动将event对象作为参数传给监听的处理函数,函数内部可直接通过
e.type判断事件类型。 - 每个选择器对应独立的节流实例,避免了原代码中多次调用同一个
equalizer函数时,节流状态共享可能导致的执行异常。
内容的提问来源于stack exchange,提问作者Ayhan
相关产品推荐
相关产品推荐

