if () { debouce(()={}); } else { immediate(); } 的尝试不起作用的原因是事件处理程序如何存储函数以及 debounce 如何存储其计时器。
当您运行.on("input", function() { }) 时,该函数定义存储在事件处理程序中,准备运行。然而,对于去抖动,这不是正在做的事情,而是:
.on("input", function())
没有函数定义 - 它调用函数本身,当事件运行时恰好返回另一个要调用的函数。
这就是为什么有这么多关于 SO 的问题,比如“我的代码在我执行 .on("input", myfunction()) 时会立即运行,而应该是 .on("input", myfunction)
因此,一个函数(去抖动)在每个事件设置中运行一次 - 不是在每个 input 事件触发时运行一次,而是在设置事件时运行一次。所以只有一个 var timer 实例,它都包含在 debounce 函数中。然后事件触发调用 return function() 内的代码,该代码已经在其外部范围内定义了 var timer(之前的去抖调用)。
如果您使用第二个输入 $("#secondInp").on("input", debounce(() => ... 再次调用 debounce,您将获得具有自己变量的函数的第二个实例(因此它们不会在 inp1 和 inp2 之间发生冲突)。
所以你可以看到,如果你把它放在事件处理程序中(在if 中),你每次都会调用 new debounce(不是同一个)。
您的尝试什么也没做,因为您的代码 debounce(function(){CheckMe.show();},500) 只是返回函数 - 所以您需要这样做
debounce(function(){CheckMe.show();},500)();`
但即使这样也不会起作用,因为每次它被调用(每个事件)你会得到一个 debounce 函数的新实例和一个 var timer 的新实例。
您可以使用两个事件。在每个事件中检查是否应该显示“检查我”。
debounced 将在 500 毫秒后运行,未去抖动的将立即运行。
function debounce(fn, duration) {
var timer;
return function() {
clearTimeout(timer);
timer = setTimeout(fn, duration);
}
}
$(document).ready(function() {
const textField = $("#textField");
const checkMe = $("#checkMe");
checkMe.hide();
textField.on("input", debounce(() => {
if (textField.val()) {
checkMe.show();
}
}, 500));
textField.on("input", () => {
if (!textField.val()) {
checkMe.hide();
}
});
});
#checkMe { color: red; }
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<input id="textField" type="text">
<div id='checkMe'>^-- check this</div>
是否可以将其保存在单个 if-else 中
鉴于上述解释,您无法按原样使用您的debounce 函数;因为return function() { } 和timer 的单个实例。关键是timer的单个实例。
如果没有去抖,这可以在单个函数中实现,使用一个 outer 变量作为计时器,但每次都需要重复去抖代码(例如,对于第二个输入) - 只是clearTimeout 和 setTimeout 代码 - 不多 - 成为问题的是“全局”/外部范围变量。
$(document).ready(function() {
var textFieldTimer = null;
const textField = $("#textField");
const checkMe = $("#checkMe");
checkMe.hide();
textField.on("input", () => {
if (textField.val()) {
clearTimeout(textFieldTimer);
textFieldTimer = setTimeout(() => checkMe.show(), 500);
}
else {
checkMe.hide();
}
});
});
#checkMe { color: red; }
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<input id="textField" type="text">
<div id='checkMe'>^-- check this</div>
那么我们如何同时使用:可重用函数和事件处理程序内部的if?
通过在元素本身上存储 timer 的单个实例 - 在下面的代码中使用 .data(),但任何为每个元素存储单个实例的方法也可以工作。
这是一个示例,使用带有 if 的单个事件并重复第二个输入以显示其工作原理。
function debounce2(fn, duration)
{
var timer = $(this).data("timer");
clearTimeout(timer);
$(this).data("timer", setTimeout(fn, duration));
}
$(document).ready(function() {
$("#checkMe, #checkMe2").hide();
$("#textField, #textField2").on("input", function() {
if ($(this).val()) {
debounce2.call(textField, () => $("#checkMe").show(), 500);
}
else {
$("#checkMe").hide();
}
});
// second input confirming `timer` is per element.
$("#textField2").on("input", function() {
if ($(this).val()) {
debounce2.call(textField, () => $("#checkMe2").show(), 500);
}
else {
$("#checkMe2").hide();
}
});
});
#checkMe, #checkMe2 { color: red; }
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<input id="textField" type="text">
<div id='checkMe'>^-- check this</div>
<hr/>
<input id="textField2" type="text">
<div id='checkMe2'>^-- check this</div>