【发布时间】:2021-02-17 13:46:32
【问题描述】:
我使用闭包来确保绑定到元素的众多事件中只有一个被执行,例如:$('.textInputs').on('keyup.my.evt change.my.evt', once(options));
我在once 函数闭包中使用了下划线的_.debounce。如果我对一个输入进行更改并在更改另一个输入之前等待,那么一切正常。如果我在一个输入中进行更改并快速切换到下一个输入并在第一个输入的时间等待到期之前一秒钟进行更改,则仅对第二个输入执行去抖动功能。这告诉我两个输入都使用从 debounce 返回的相同函数,但我不确定如何更改我的代码结构,以便每个输入都使用它们自己的 debounce 函数。
去抖函数:
var doStuff = function(eleObj, options){ console.log(eleObj, options); } // the function that does stuff
var debouncedDoStuff = _debounce(doStuff, 2000); // debouncing doStuff()
一次闭包定义:
var once = function (options) {
var eventType = null;
function doOnce(e) {
if (!eventType) {
eventType = e.type; // only the first eventType we get will be registered
}
if (e.type == eventType) {
debouncedDoStuff($(this), options); // calling the debounced do stuff func
}
}
return doOnce;
}
文档准备就绪:
$(document).ready(function(){
var options = {foo:'bar', baz:'biz'};
$('.textInputs').on('keyup.my.evt change.my.evt', once(options));
});
我做了一个小提琴来演示这个问题: https://jsfiddle.net/enzt7q90/
澄清说明 上面的代码已减少到显示问题的最低限度。实际目标是将 doStuff 附加到 ajax 进程,以保存对表格数据所做的任何更改。
我还应该指出,once 闭包不像 jQuery 的 .one()。例如, .one('keyup change', function(){}) 将在按下 Tab 键时执行 func 两次(一次用于 keyup,再次用于更改),而我使用一次关闭的方式仅为这两个事件执行一次。
【问题讨论】:
-
这是因为 debounce 函数会删除第一个注册的元素并在您按下另一个按钮时注册一个新元素。请编辑您的帖子并说出您想要实现的目标。
-
我希望 doStuff 在 2 秒去抖动计时器到期时对所有具有 keyup 或 change 事件的输入执行。
-
那么您将需要为每个元素添加该去抖动功能,我真的对 jquery 一无所知,但作为一个猜测,这段代码正在整个元素上执行。 注意 debounce 函数返回一个函数,所以每当按下一个元素时,它都会改变闭包中的外部变量,所以你想在每个元素上调用 debounce
-
我想出了一个解决方案,将去抖动的函数引用存储在元素数据堆栈中。虽然这看起来很笨拙,所以我希望有人可以展示正确的结构。 (编辑小提琴:jsfiddle.net/w85aef1o)
标签: javascript jquery closures underscore.js debouncing