Запуск функции JavaScript после завершения ввода пользователем, а не при отпускании клавиши?
Я хочу выполнить AJAX-запрос, когда пользователь завершит ввод в текстовом поле. Необходимо, чтобы функция не срабатывала при каждом введенном символе, так как это приведет к большому количеству AJAX-запросов, но и не хочу, чтобы пользователю приходилось нажимать кнопку "Enter" для этого.
Есть ли способ определить, когда пользователь завершил ввод, и затем выполнить AJAX-запрос?
Я использую jQuery.
5 ответ(ов)
Да, ваше предположение о том, что "завершение ввода" означает кратковременную паузу (например, 5 секунд), вполне верно. При этом мы можем установить таймер, когда пользователь отпускает клавишу, и сбросить его при нажатии клавиши. В примере ниже ввод, о котором идет речь, обозначен как #myInput
.
Делаем несколько предположений...
// Инициализация переменных перед функциями
var typingTimer; // идентификатор таймера
var doneTypingInterval = 5000; // время в миллисекундах, например 5 секунд
var $input = $('#myInput');
// При отпускании клавиши запускаем обратный отсчет
$input.on('keyup', function () {
clearTimeout(typingTimer);
typingTimer = setTimeout(doneTyping, doneTypingInterval);
});
// При нажатии клавиши сбрасываем обратный отсчет
$input.on('keydown', function () {
clearTimeout(typingTimer);
});
// Пользователь "завершил ввод", выполняем нужное действие
function doneTyping () {
// выполняем нужное действие
}
Таким образом, данный пример кода устанавливает таймер на 5 секунд после последнего ввода пользователя. Если пользователь начнет вводить текст снова (нажмет клавишу), таймер сбрасывается, и процесс начинается заново. Когда пользователь останавливается на 5 секунд, выполняется функция doneTyping
, где можно реализовать необходимое действие.
Ответ, выбранный выше, не работает.
Проблема в том, что typingTimer
иногда устанавливается несколько раз (например, если пользователь быстро нажимает клавиши — несколько раз keyup
происходит до того, как сработает keydown
), из-за чего таймер неправильно очищается.
Предложенное ниже решение устраняет эту проблему и вызывает функцию doneTyping
через X секунд после окончания ввода, как и запрашивалось автором вопроса. Также больше не требуется излишняя функция keydown
. Я добавил проверку, чтобы ваша функция не вызывалась в случае, если поле ввода пустое.
// Подготовка перед функциями
var typingTimer; // идентификатор таймера
var doneTypingInterval = 5000; // время в мс (5 секунд)
// При отпускании клавиши начинается обратный отсчет
$('#myInput').keyup(function() {
clearTimeout(typingTimer);
if ($('#myInput').val()) {
typingTimer = setTimeout(doneTyping, doneTypingInterval);
}
});
// Пользователь "закончил ввод", выполняем действие
function doneTyping () {
// выполнить какое-то действие
}
И аналогичный код на чистом JavaScript:
// Подготовка перед функциями
let typingTimer; // идентификатор таймера
let doneTypingInterval = 5000; // время в мс (5 секунд)
let myInput = document.getElementById('myInput');
// При отпускании клавиши начинается обратный отсчет
myInput.addEventListener('keyup', () => {
clearTimeout(typingTimer);
if (myInput.value) {
typingTimer = setTimeout(doneTyping, doneTypingInterval);
}
});
// Пользователь "закончил ввод", выполняем действие
function doneTyping () {
// выполнить какое-то действие
}
Это решение использует ES6, но это не обязательно. Просто замените let
на var
и стрелочную функцию на обычную функцию.
Это всего лишь одна строка с использованием функции debounce
библиотеки underscore.js:
$('#my-input-box').keyup(_.debounce(doSomething, 500));
Это значит, что функция doSomething будет вызвана через 500 миллисекунд после того, как я перестану набирать текст.
Для получения дополнительной информации, можно посетить: http://underscorejs.org/#debounce
Да, вы можете установить таймаут, скажем, в 2 секунды для каждого события key up, чтобы запускать AJAX-запрос. Также вы можете сохранить объект XHR и прервать его при последующих нажатиях клавиш, чтобы сэкономить больше трафика. Вот пример, который я написал для своего скрипта автозаполнения.
var timer;
var x;
$(".some-input").keyup(function () {
if (x) { x.abort() } // Если существует текущий XHR, прерываем его.
clearTimeout(timer); // Очищаем таймер, чтобы избежать дубликатов.
timer = setTimeout(function() { // устанавливаем новый таймаут
x = $.getJSON(...); // выполняем AJAX-запрос и сохраняем в переменной x (чтобы можно было отменить)
}, 2000); // задержка 2000мс, измените для ускорения/замедления
});
Надеюсь, это поможет!
Марко
Ваш код предназначен для того, чтобы отслеживать ввод текста в элементе с id in
и выполнять определенные действия с задержкой в 1000 мс (1 секунда) после последнего нажатия клавиши. Однако есть некоторые моменты, которые необходимо исправить. Вот исправленный и улучшенный вариант вашего кода:
var timer;
var timeout = 1000;
$('#in').keyup(function(){
clearTimeout(timer);
// Проверяем, что поле input не пустое
if ($('#in').val()) {
timer = setTimeout(function(){
// Выполняем нужное действие здесь, например, AJAX-запрос и т.д.
var v = $("#in").val();
$("#out").html(v);
}, timeout);
}
});
Что было исправлено:
Проверка значения: В вашем коде была ошибка в условии
if ($('#in').val)
. Правильный способ проверки поля ввода на наличие значения - использоватьif ($('#in').val())
, так какval
— это метод, который нужно вызывать, чтобы получить текущее значение поля.Описание работы кода: Я добавил комментарий, поясняющий, какие действия будут выполняться после задержки.
Общее объяснение:
Этот код использует свойство keyup
, чтобы отслеживать нажатия клавиш в поле ввода. Если пользователь печатает, предыдущий таймер сбрасывается, и новый таймер запускается. Как только пользователь перестает печатать на одну секунду, текущее значение текстового поля #in
берется и отображается в элементе #out
.
Полный пример:
Вы можете найти полный пример вашего кода по следующей ссылке: jsfiddle.net
Как перенаправить на другую веб-страницу?
Прокрутка к элементу с использованием jQuery
jQuery: Получение Выбранного Значения Из Выпадающего Списка
Существует ли ссылка на "последнюю" библиотеку jQuery в Google APIs?
Как определить нажатие клавиши Esc?