Как вызвать событие во входном тексте после прекращения ввода/записи?

Я хочу вызвать событие сразу после того, как я перестаю печатать (не во время ввода) символы в текстовом поле ввода.

Я пробовал:

$('input#username').keypress(function() {
    var _this = $(this); // copy of this object for further usage

    setTimeout(function() {
        $.post('/ajax/fetch', {
            type: 'username',
            value: _this.val()
        }, function(data) {
            if(!data.success) {
                // continue working
            } else {
                // throw an error
            }
        }, 'json');
    }, 3000);
});

Но этот пример создает тайм-аут для каждого типизированного символа, и я получаю около 20 запросов AJAX, если я вводим 20 символов.

На этой скрипте я демонстрирую ту же проблему с простым предупреждением, а не с AJAX.

Есть ли решение для этого или я просто использую плохой подход для этого?

Ответ 1

Вам нужно будет использовать setTimeout (как и вы), но также сохранить ссылку, чтобы вы могли сбросить лимит. Что-то вроде:

//
// $('#element').donetyping(callback[, timeout=1000])
// Fires callback when a user has finished typing. This is determined by the time elapsed
// since the last keystroke and timeout parameter or the blur event--whichever comes first.
//   @callback: function to be called when even triggers
//   @timeout:  (default=1000) timeout, in ms, to to wait before triggering event if not
//              caused by blur.
// Requires jQuery 1.7+
//
;(function($){
    $.fn.extend({
        donetyping: function(callback,timeout){
            timeout = timeout || 1e3; // 1 second default timeout
            var timeoutReference,
                doneTyping = function(el){
                    if (!timeoutReference) return;
                    timeoutReference = null;
                    callback.call(el);
                };
            return this.each(function(i,el){
                var $el = $(el);
                // Chrome Fix (Use keyup over keypress to detect backspace)
                // thank you @palerdot
                $el.is(':input') && $el.on('keyup keypress paste',function(e){
                    // This catches the backspace button in chrome, but also prevents
                    // the event from triggering too preemptively. Without this line,
                    // using tab/shift+tab will make the focused element fire the callback.
                    if (e.type=='keyup' && e.keyCode!=8) return;
                    
                    // Check if timeout has been set. If it has, "reset" the clock and
                    // start over again.
                    if (timeoutReference) clearTimeout(timeoutReference);
                    timeoutReference = setTimeout(function(){
                        // if we made it here, our timeout has elapsed. Fire the
                        // callback
                        doneTyping(el);
                    }, timeout);
                }).on('blur',function(){
                    // If we can, fire the event since we're leaving the field
                    doneTyping(el);
                });
            });
        }
    });
})(jQuery);

$('#example').donetyping(function(){
  $('#example-output').text('Event last fired @ ' + (new Date().toUTCString()));
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>

<input type="text" id="example" />
<p id="example-output">Nothing yet</p>

Ответ 2

РЕШЕНИЕ:

Вот решение. Выполнение функции после того, как пользователь прекратил печатать в течение определенного времени:

var delay = (function(){
  var timer = 0;
  return function(callback, ms){
  clearTimeout (timer);
  timer = setTimeout(callback, ms);
 };
})();

Использование

$('input').keyup(function() {
  delay(function(){
    alert('Hi, func called');
  }, 1000 );
});

Ответ 3

Вы можете использовать underscore.js "debounce"

$('input#username').keypress( _.debounce( function(){<your ajax call here>}, 500 ) );

Это означает, что ваш вызов функции будет выполняться после 500 мс нажатия клавиши. Но если вы нажмете еще одну клавишу (другое событие нажатия клавиши) перед 500 мс, предыдущее выполнение функции будет проигнорировано (отменено), а новое будет выполнено после нового 500 мс таймера.

За дополнительной информацией, использование функции _.debounce(func, timer, true) означает, что первая функция будет выполнена, а все остальные события нажатия клавиш с последующими таймерами 500 мс будут проигнорированы.

Ответ 4

Вам нужно дебютировать!

Вот плагин jQuery, и вот все, что вам нужно знать о debounce. Если вы приезжаете сюда из Google, и Underscore нашел свой путь в JSoup вашего приложения, у него есть debounce испеченный прямо в!

Ответ 5

очищенный раствор:

$.fn.donetyping = function(callback, delay){
  delay || (delay = 1000);
  var timeoutReference;
  var doneTyping = function(elt){
    if (!timeoutReference) return;
    timeoutReference = null;
    callback(elt);
  };

  this.each(function(){
    var self = $(this);
    self.on('keyup',function(){
      if(timeoutReference) clearTimeout(timeoutReference);
      timeoutReference = setTimeout(function(){
        doneTyping(self);
      }, delay);
    }).on('blur',function(){
      doneTyping(self);
    });
  });

  return this;
};

Ответ 6

Существует несколько простых плагинов, которые я сделал, что делает это намного глубже. Он требует гораздо меньше кода, чем предлагаемые решения, и он очень легкий (~ 0,6kb)

Сначала вы создаете объект Bid, чем может быть bumped в любое время. Каждый удар замедляет обратный вызов Bid для следующего заданного времени.

var searchBid = new Bid(function(inputValue){
    //your action when user will stop writing for 200ms. 
    yourSpecialAction(inputValue);
}, 200); //we set delay time of every bump to 200ms

Когда объект Bid готов, нам нужно bump его каким-то образом. Пусть прикрепляется наклон к keyup event.

$("input").keyup(function(){
    searchBid.bump( $(this).val() ); //parameters passed to bump will be accessable in Bid callback
});

Что происходит здесь:

Каждый пользователь нажимает клавишу, ставка "задерживается" (набивается) на следующие 200 мс. Если 200 мс пройдут без лишних ударов, обратный вызов будет запущен.

Кроме того, у вас есть две дополнительные функции для остановки ставки (если пользователь нажал esc или нажал внешний вход, например), а также для немедленного завершения и немедленного завершения обратного вызова (например, когда пользователь нажимает клавишу ввода):

searchBid.stop();
searchBid.finish(valueToPass);

Ответ 7

Я искал простой код HTML/JS, и я не нашел его. Затем я написал код ниже с помощью onkeyup="DelayedSubmission()".

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="pt-br" lang="pt-br">
<head><title>Submit after typing finished</title>
<script language="javascript" type="text/javascript">
function DelayedSubmission() {
    var date = new Date();
    initial_time = date.getTime();
    if (typeof setInverval_Variable == 'undefined') {
            setInverval_Variable = setInterval(DelayedSubmission_Check, 50);
    } 
}
function DelayedSubmission_Check() {
    var date = new Date();
    check_time = date.getTime();
    var limit_ms=check_time-initial_time;
    if (limit_ms > 800) { //Change value in milliseconds
        alert("insert your function"); //Insert your function
        clearInterval(setInverval_Variable);
        delete setInverval_Variable;
    }
}

</script>
</head>
<body>

<input type="search" onkeyup="DelayedSubmission()" id="field_id" style="WIDTH: 100px; HEIGHT: 25px;" />

</body>
</html>

Ответ 8

По моему мнению, пользователь перестает писать, когда не сосредотачивается на этом входе. Для этого у вас есть функция "размытие", которая делает материал как