Как вызвать событие onkeyup, которое задерживается до тех пор, пока пользователь не остановит их ввод?
У меня есть текстовое поле, где люди вводят какой-то текст (естественно), и я хочу сделать так, чтобы запрос AJAX делался время от времени, чтобы получить некоторые предложения относительно того, что такое textarea (например, переполнение стека) но для текстового поля, а не для ввода текста). Проблема в том, что я не могу выполнить запрос AJAX на каждом нажатии клавиши (это было бы бесполезно и очень ресурсоемким), и я не уверен, что было бы самым эффективным способом сделать это (каждые X слов? Каждые X секунд? или что-то еще?).
Каким будет лучший способ сделать это?
Спасибо заранее.
Ответы
Ответ 1
Вы можете объединить обработчик событий keypress
с setTimeout
, чтобы вы отправили Ajax-запрос определенное количество времени после нажатия клавиши, отмены и перезапуска таймера, если другое нажатие клавиши происходит до окончания таймера. Предполагая, что у вас есть текстовое поле с id 'myTextArea' и функция обратного вызова Ajax, называемая doAjaxStuff
:
function addTextAreaCallback(textArea, callback, delay) {
var timer = null;
textArea.onkeypress = function() {
if (timer) {
window.clearTimeout(timer);
}
timer = window.setTimeout( function() {
timer = null;
callback();
}, delay );
};
textArea = null;
}
addTextAreaCallback( document.getElementById("myTextArea"), doAjaxStuff, 1000 );
Ответ 2
Другой альтернативой является использование небольшого плагина jQuery под названием bindWithDelay. Он использует тот же метод setTimeout, что и принятый ответ, но прозрачно обрабатывает таймауты, поэтому ваш код немного легче читать. Исходный код можно увидеть на github.
$("#myTextArea").bindWithDelay("keypress", doAjaxStuff, 1000)
Ответ 3
То, что вы ищете, называется debouncing
. Вот общий алгоритм в языке JavaScript:
function debounce(fn, duration) {
var timer;
return function() {
clearTimeout(timer);
timer = setTimeout(fn, duration)
}
}
И вот пример того, как использовать его с событием onkeyup
:
function debounce(fn, duration) {
var timer;
return function(){
clearTimeout(timer);
timer = setTimeout(fn, duration);
}
}
$(function(){
$('#txtSearch').on('keyup', debounce(function(){
alert('You paused your typing!');
}, 500));
});
input{
padding:.5em;
font-size:16px;
width:20em;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<input id="txtSearch" placeholder="Type here" />
Ответ 4
Если вы используете underscore.js, вы можете использовать функцию debounce.
Пример (jQuery, используемый для keyup):
$('#myTextArea').keyup(_.debounce(function(){
alert('hello');
}, 500));
Ответ 5
Я лично использовал бы setInterval
, который будет отслеживать текстовое поле для изменений и выполнять только обратные вызовы AJAX, когда он обнаруживает изменение. каждая секунда должна быть быстрой и достаточно медленной.
Ответ 6
Если вас интересуют решения jQuery, jQuery Suggest является хорошей реализацией.
Нет смысла изобретать колесо каждый раз.
Ответ 7
Если вы используете эту функцию много вокруг сайта и не хотите отслеживать все ссылки setTimeout и т.д., тогда я упаковал это в плагин, доступный .
Плагин добавляет несколько параметров в обычный метод $.ajax для буферизации и отмены предыдущих вызовов ajax.