当用户在文本框中输入完成时,我想触发一个 ajax 请求。我不希望它在每次用户键入字母时都运行该函数,因为这会导致很多 ajax 请求,但是我也不希望他们必须点击输入按钮。
有没有办法让我可以检测到用户何时完成输入然后执行 ajax 请求?
在这里使用jQuery!戴夫
当用户在文本框中输入完成时,我想触发一个 ajax 请求。我不希望它在每次用户键入字母时都运行该函数,因为这会导致很多 ajax 请求,但是我也不希望他们必须点击输入按钮。
有没有办法让我可以检测到用户何时完成输入然后执行 ajax 请求?
在这里使用jQuery!戴夫
所以,我猜想完成打字意味着你只是停下来一段时间,比如 5 秒。因此,考虑到这一点,让我们在用户释放一个键时启动一个计时器,并在他们按下一个键时清除它。我决定有问题的输入将是#myInput。
做一些假设...
//setup before functions
var typingTimer; //timer identifier
var doneTypingInterval = 5000; //time in ms, 5 second for example
var $input = $('#myInput');
//on keyup, start the countdown
$input.on('keyup', function () {
clearTimeout(typingTimer);
typingTimer = setTimeout(doneTyping, doneTypingInterval);
});
//on keydown, clear the countdown
$input.on('keydown', function () {
clearTimeout(typingTimer);
});
//user is "finished typing," do something
function doneTyping () {
//do something
}
上面选择的答案不起作用。
因为 TypingTimer 偶尔会设置多次(在为快速打字机等触发 keydown 之前按下 keyup 两次),所以它不能正确清除。
下面的解决方案解决了这个问题,并会在完成 OP 请求后调用 X 秒。它也不再需要冗余的 keydown 功能。我还添加了一个检查,以便在您的输入为空时不会发生您的函数调用。
//setup before functions
var typingTimer; //timer identifier
var doneTypingInterval = 5000; //time in ms (5 seconds)
//on keyup, start the countdown
$('#myInput').keyup(function(){
clearTimeout(typingTimer);
if ($('#myInput').val()) {
typingTimer = setTimeout(doneTyping, doneTypingInterval);
}
});
//user is "finished typing," do something
function doneTyping () {
//do something
}
和 vanilla JavaScript 解决方案中的相同代码:
//setup before functions
let typingTimer; //timer identifier
let doneTypingInterval = 5000; //time in ms (5 seconds)
let myInput = document.getElementById('myInput');
//on keyup, start the countdown
myInput.addEventListener('keyup', () => {
clearTimeout(typingTimer);
if (myInput.value) {
typingTimer = setTimeout(doneTyping, doneTypingInterval);
}
});
//user is "finished typing," do something
function doneTyping () {
//do something
}
该解决方案确实使用了 ES6,但这里没有必要。只需将let
withvar
和箭头函数替换为常规函数即可。
它只是带有underscore.js去抖动功能的一行:
$('#my-input-box').keyup(_.debounce(doSomething , 500));
这基本上是在我停止打字后 500 毫秒执行doSomething。
更多信息:http : //underscorejs.org/#debounce
是的,您可以在每个按键事件上设置 2 秒的超时时间,这将触发 ajax 请求。您还可以存储 XHR 方法并在后续按键事件中中止它,以便您节省更多带宽。这是我为我的自动完成脚本编写的内容。
var timer;
var x;
$(".some-input").keyup(function () {
if (x) { x.abort() } // If there is an existing XHR, abort it.
clearTimeout(timer); // Clear the timer so we don't end up with dupes.
timer = setTimeout(function() { // assign timer a new timeout
x = $.getJSON(...); // run ajax request and store in x variable (so we can cancel)
}, 2000); // 2000ms delay, tweak for faster/slower
});
希望这可以帮助,
马可
迟到的答案,但我添加它是因为它是 2019 年,这完全可以使用漂亮的 ES6 实现,没有第三方库,而且我发现大多数高评价的答案都很笨重,而且变量太多。
function debounce(callback, wait) {
let timeout;
return (...args) => {
clearTimeout(timeout);
timeout = setTimeout(function () { callback.apply(this, args); }, wait);
};
}
window.addEventListener('keyup', debounce( () => {
// code you would like to run 1000ms after the keyup event has stopped firing
// further keyup events reset the timer, as expected
}, 1000))