jQuery自定义resized方法仅执行一次的问题求助
问题分析
你的核心问题是:每次调用resized方法时,都会给window绑定新的resize事件处理函数,这些函数共享同一个resizeTimeout数据。窗口resize触发时,先注册的处理函数刚设置完定时器,后注册的就会立刻清除它并替换成自己的,最终只有最后一个回调能执行。另外你用$.each修改的方式完全错误,$.each不能用来定义jQuery插件方法。
解决方案
下面提供两种可行的实现方式,按需选择:
方案一:每个回调独立维护定时器(支持不同延迟时间)
这种方式可以给不同的回调设置不同的延迟时长,每个回调的定时器相互独立:
$.fn.resized = function(callback, timeout = 300) { return this.each(function() { const $elem = $(this); // 初始化回调存储队列 let callbacks = $elem.data('resizeCallbacks') || []; callbacks.push({ callback, timeout }); $elem.data('resizeCallbacks', callbacks); // 仅给元素绑定一次resize事件 if (!$elem.data('resizeBound')) { $elem.resize(function() { const callbacks = $elem.data('resizeCallbacks') || []; callbacks.forEach(item => { if (item.timerId) clearTimeout(item.timerId); item.timerId = setTimeout(item.callback, item.timeout); }); }); $elem.data('resizeBound', true); } }); };
方案二:统一延迟执行所有回调(性能更优,适合同延迟场景)
如果所有回调都用相同的延迟时间,这种方式只维护一个定时器,延迟结束后批量执行所有回调:
$.fn.resized = function(callback, timeout = 300) { return this.each(function() { const $elem = $(this); // 存储回调队列 let callbacks = $elem.data('resizeCallbacks') || []; callbacks.push(callback); $elem.data('resizeCallbacks', callbacks); // 仅绑定一次resize事件 if (!$elem.data('resizeBound')) { $elem.resize(function() { const timerId = $elem.data('resizeTimeout'); if (timerId) clearTimeout(timerId); const newTimerId = setTimeout(() => { const callbacks = $elem.data('resizeCallbacks') || []; callbacks.forEach(cb => cb()); }, timeout); $elem.data('resizeTimeout', newTimerId); }); $elem.data('resizeBound', true); } }); };
调用方式
你的原有调用代码无需修改,直接使用即可:
jQuery(window).load(function() { $(window).resized(function() { console.log('Test 1'); }, 300); $(window).resized(function() { console.log('Test 2'); }, 300); });
内容的提问来源于stack exchange,提问作者Jandon
相关产品推荐
相关产品推荐

