Причина, по которой попытка с if () { debouce(()={}); } else { immediate(); }
не работает, связана с тем, как обработчики событий хранят функцию и как debounce хранит свой таймер.
Когда вы запускаете .on("input", function() { }
), это определение функции сохраняется в обработчике событий и готово к запуску. Однако с debounce это не то, что делается, вместо этого:
.on("input", function())
нет функции definition — она вызывает саму функцию, которая возвращает другую функцию, которая будет вызываться при выполнении события.
Вот почему так много вопросов о SO, говорящих, что что-то вроде моего кода запускается немедленно, когда я делаю .on("input", myfunction())
, когда это должно быть .on("input", myfunction)
Таким образом, одна функция (отмена дребезга) запускается один раз при настройке события — не один раз при input
срабатывании события, а только один раз при настройке события. Итак, есть только один экземпляр var timer
, и все они содержатся в функции debounce. Затем событие fire вызывает код внутри return function()
, который уже имеет var timer
, определенный ранее во внешней области (предыдущий вызов debounce).
Если вы снова вызовете debounce со вторым входом $("#secondInp").on("input", debounce(() => ...
, вы получите второй экземпляр функции со своей собственной переменной (чтобы они не конфликтовали между inp1 и inp2).
Таким образом, вы можете видеть, что если вы поместите это в обработчик событий (в if
), вы будете вызывать новый debounce каждый раз (не один и тот же).
Ваша попытка ничего не дала, потому что ваш код debounce(function(){CheckMe.show();},500)
просто возвращает функцию, поэтому вам нужно будет сделать
debounce(function(){CheckMe.show();},500)();`
но даже это не сработает, так как каждый раз вызывается (каждое событие), вы получаете новый экземпляр функции debounce и новый экземпляр var timer
.
Вы можете использовать два события. Внутри каждого события проверьте, должен ли отображаться check me или нет.
debounce
d запустится через 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
.
Без устранения дребезга это можно реализовать в одной функции, используя внешнюю переменную для таймера, но потребуется каждый раз повторять код устранения дребезга (например, для 2-го входа) — только 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>
person
freedomn-m
schedule
06.04.2021
textField
пуст, т. е. вызовCheckMe.hide()
никогда не должен откладываться, аCheckMe.show()
должен откладываться на 500 мс после того, как пользователь перестает печатать - person CutePoison   schedule 06.04.2021priceThreshold
иtextField
- они одинаковы, просто опечатка в вопросе? - person freedomn-m   schedule 06.04.2021