Uruchom funkcję javascript, gdy Użytkownik skończy pisać zamiast na klawiaturze?

Chcę wywołać żądanie ajax, gdy Użytkownik skończy pisać w polu tekstowym. Nie chcę, aby uruchamiał funkcję za każdym razem, gdy użytkownik wpisze literę, ponieważ spowodowałoby to wiele żądań ajax, jednak nie chcę, aby musieli nacisnąć przycisk enter.

Czy Jest jakiś sposób, abym mógł wykryć, kiedy użytkownik skończył pisać, a następnie wykonać żądanie ajax?

Używanie jQuery tutaj! Dave

Author: Macmee, 2010-11-19

22 answers

Zgaduję, że dokończenie pisania oznacza, że zatrzymasz się na chwilę, powiedzmy 5 sekund. Mając to na uwadze, pozwala uruchomić timer, gdy użytkownik zwolni klucz i wyczyścić go po naciśnięciu jednego. Zdecydowałem, że dane wejściowe będą #myInput.

Dokonując kilku założeń...

//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
}
 527
Author: Surreal Dreams,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-07-16 20:32:41

Wybrana powyżej odpowiedź nie działa.

Ponieważ typingTimer jest ustawiany wielokrotnie (keyup naciśnięty dwukrotnie przed uruchomieniem keydown dla szybkich Typerów itp.), to nie jest dokładnie jasne.

Poniższe rozwiązanie rozwiązuje ten problem i wywoła X sekund po zakończeniu, zgodnie z żądanym OP. Nie wymaga już również redundantnej funkcji keydown. Dodałem również czek, aby nie doszło do wywołania funkcji, jeśli twoje wejście jest puste.

//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
}

Oraz ten sam kod w vanilla JavaScript solution:

//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
}

To rozwiązanie nie używa ES6, ale nie jest to konieczne tutaj. Wystarczy zamienić let na var, a funkcję strzałki na funkcję regularną.

 303
Author: going,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-08-17 20:12:17

To tylko Jedna linia z podkreśleniem.JS funkcja debounce:

$('#my-input-box').keyup(_.debounce(doSomething , 500));

To w zasadzie mówidoSomething 500 milisekund po tym, jak przestałem pisać.

Więcej informacji: http://underscorejs.org/#debounce

 67
Author: bit2pixel,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-04-13 12:53:48

Tak, możesz ustawić limit czasu powiedzmy 2 sekund na każdym zdarzeniu key up, które odpali żądanie ajax. Można również zapisać metodę XHR i przerywać ją przy kolejnych naciśnięciach klawiszy, dzięki czemu można zapisać jeszcze więcej. Oto coś, co napisałem dla mojego autouzupełniania.

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
});

Mam nadzieję, że to pomoże,

Marko

 39
Author: Marko,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-11-18 22:19:53
var timer;
var timeout = 1000;

$('#in').keyup(function(){
    clearTimeout(timer);
    if ($('#in').val) {
        timer = setTimeout(function(){
            //do stuff here e.g ajax call etc....
             var v = $("#in").val();
             $("#out").html(v);
        }, timeout);
    }
});

Pełny przykład tutaj: http://jsfiddle.net/ZYXp4/8/

 16
Author: azzy81,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-08-14 13:11:25

Podoba mi się surrealistyczna odpowiedź snu, ale odkryłem, że moja funkcja "doneTyping "odpala się za każde naciśnięcie klawisza, tzn. jeśli wpiszesz" Hello " naprawdę szybko; zamiast odpalić tylko raz, gdy przestaniesz pisać, funkcja odpali 5 razy.

Problem polegał na tym, że funkcja javascript setTimeout nie wydaje się nadpisywać ani zabijać starych timeoutów, które zostały ustawione, ale jeśli zrobisz to sam, to działa! Więc właśnie dodałem wywołanie clearTimeout tuż przed setTimeout, jeśli typingTimer jest gotowi. Patrz poniżej:

//setup before functions
var typingTimer;                //timer identifier
var doneTypingInterval = 5000;  //time in ms, 5 second for example

//on keyup, start the countdown
$('#myInput').on("keyup", function(){
    if (typingTimer) clearTimeout(typingTimer);                 // Clear if already set     
    typingTimer = setTimeout(doneTyping, doneTypingInterval);
});

//on keydown, clear the countdown 
$('#myInput').on("keydown", function(){
    clearTimeout(typingTimer);
});

//user is "finished typing," do something
function doneTyping () {
    //do something
}

N. B. chciałbym dodać to jako komentarz do odpowiedzi Surreal Dream, ale jestem nowym użytkownikiem i nie mam wystarczającej reputacji. Przepraszam!

 9
Author: Liam Flanagan,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-01-15 11:07:54

Modyfikowanie zaakceptowanej odpowiedzi w celu obsługi dodatkowych przypadków, takich jak wklejanie:

//setup before functions
var typingTimer;                //timer identifier
var doneTypingInterval = 2000;  //time in ms, 2 second for example
var $input = $('#myInput');

// updated events 
$input.on('input propertychange paste', function () {
    clearTimeout(typingTimer);
    typingTimer = setTimeout(doneTyping, doneTypingInterval);      
});

//user is "finished typing," do something
function doneTyping () {
  //do something
}
 8
Author: Jecoms,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-08-30 18:45:21

Cóż, ściśle mówiąc nie, ponieważ komputer nie może odgadnąć, kiedy użytkownik skończył pisać. Można oczywiście odpalić timer przy key up i zresetować go przy każdym kolejnym key up. Jeśli timer wygaśnie, użytkownik nie wpisał czasu trwania timera - można to nazwać "zakończonym pisaniem".

Jeśli oczekujesz, że użytkownicy będą robić przerwy podczas pisania, nie ma sposobu, aby wiedzieć, kiedy są one zrobione.

(o ile oczywiście na podstawie danych można stwierdzić, kiedy są zrobione)

 4
Author: sleske,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-11-18 22:16:03

Nie sądzę, aby Zdarzenie keyDown było w tym przypadku konieczne (proszę mi powiedzieć, dlaczego, jeśli się mylę). W moim skrypcie (nie-jquery) podobne rozwiązanie wygląda tak:

var _timer, _timeOut = 2000; 



function _onKeyUp(e) {
    clearTimeout(_timer);
    if (e.keyCode == 13) {      // close on ENTER key
        _onCloseClick();
    } else {                    // send xhr requests
        _timer = window.setTimeout(function() {
            _onInputChange();
        }, _timeOut)
    }

}

To moja pierwsza odpowiedź na Stack Overflow, więc mam nadzieję, że kiedyś komuś to pomoże:)

 4
Author: Rafal Pastuszak,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-10-05 19:44:42

Rozwiązanie:

Realizowałem wyszukiwanie na mojej aukcji i potrzebuję, aby było oparte na Ajaxie. Oznacza to, że przy każdej zmianie klucza wyniki wyszukiwania powinny być aktualizowane i wyświetlane. To działanie skutkuje tak dużą ilością wywołań ajax wysyłanych do serwera, co nie jest dobrą rzeczą. Po kilku pracach zrobiłem podejście do serwera ping, gdy klient przestaje pisać.

Rozwiązanie zadziałało dla mnie to:

$(document).ready(function() {

$('#yourtextfield').keyup(function() {
s = $('#yourtextfield').val();
setTimeout(function() { 
        if($('#yourtextfield').val() == s){ // Check the value searched is the latest one or not. This will help in making the ajax call work when client stops writing.
            $.ajax({
                type: "POST",
                url: "yoururl",
                data: 'search=' + s,
                cache: false,
                beforeSend: function() {
                   // loading image
                },
                success: function(data) {
                    // Your response will come here
                }
            })
        }
    }, 1000); // 1 sec delay to check.

    }); // End of  keyup function

    }); // End of document.ready

Zauważyłeś, że nie ma potrzeby używania żadnego timera podczas implementacji to.

Jestem pewien, że to pomoże innym.

Ata

 2
Author: Ata ul Mustafa,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-08-28 10:03:36

Wydaje mi się, że rozwiązanie jest nieco prostsze w przypadku input:

var typingTimer;
var doneTypingInterval = 500;

$("#myInput").on("input", function () {
    window.clearTimeout(typingTimer);
    typingTimer = window.setTimeout(doneTyping, doneTypingInterval);
});

function doneTyping () {
    // code here
}
 2
Author: Adrien Brunelat,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-04-26 13:35:21

Obie top 2 odpowiedzi nie działają dla mnie. Oto moje rozwiązanie:

var timeout = null;

$('#myInput').keyup(function() {
    clearTimeout(timeout);

    timeout = setTimeout(function() {
        //do stuff here
    }, 500);
});
 2
Author: YSFKBDY,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-02-08 07:11:14

Można użyć zdarzenia onblur, aby wykryć, kiedy pole tekstowe traci ostrość: https://developer.mozilla.org/en/DOM/element.onblur

To nie to samo co "przestaje pisać", jeśli zależy ci na Przypadku, w którym użytkownik wpisuje kilka rzeczy, a następnie siedzi tam z pole tekstowe nadal koncentruje.

W tym celu sugerowałbym powiązanie setTimeout ze zdarzeniem onclick i zakładając, że po x czasie bez naciśnięć klawiszy użytkownik przestał pisać.

 1
Author: Mike Ruhlin,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-11-18 22:17:47

Oto prosty kod JS, który napisałem:

<!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>
 1
Author: Alfredo Lingoist Jr.,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-02-22 01:45:31

Po wykryciu Fokusa na polu tekstowym, po naciśnięciu klawisza sprawdź timeout i zresetuj go za każdym razem, gdy zostanie uruchomiony.

Po zakończeniu limitu czasu wykonaj żądanie ajax.

 0
Author: ocodo,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-11-18 22:16:42

Jeśli szukasz określonej długości (np. pola zipcode):

$("input").live("keyup", function( event ){
if(this.value.length == this.getAttribute('maxlength')) {
        //make ajax request here after.
    }
  });
 0
Author: Jason,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-08-09 22:15:48

Nie jestem pewien, czy moje potrzeby są trochę dziwne, ale potrzebowałem czegoś podobnego do tego i właśnie tego użyłem:

$('input.update').bind('sync', function() {
    clearTimeout($(this).data('timer'));            
    $.post($(this).attr('data-url'), {value: $(this).val()}, function(x) {
        if(x.success != true) {
            triggerError(x.message);    
        }
    }, 'json');
}).keyup(function() {
    clearTimeout($(this).data('timer'));
    var val = $.trim($(this).val());
    if(val) {
        var $this = $(this);
        var timer = setTimeout(function() {
            $this.trigger('sync');
        }, 2000);
        $(this).data('timer', timer);
    }
}).blur(function() {
    clearTimeout($(this).data('timer'));     
    $(this).trigger('sync');
});

Co pozwala mi mieć takie elementy w mojej aplikacji:

<input type="text" data-url="/controller/action/" class="update">

Które są aktualizowane, gdy użytkownik "skończył pisać" (brak akcji przez 2 sekundy) lub przechodzi do innego pola (rozmywa się z elementu)

 0
Author: Paolo Bergantino,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-10-25 16:33:14

Jeśli chcesz poczekać, aż Użytkownik skończy pisać, użyj simple this:

$(document).on('change','#PageSize', function () {
    //Do something after new value in #PageSize       
});

Kompletny przykład z wywołaniem ajax-to działa dla mojego pagera-liczba pozycji na listę:

$(document).ready(function () {
    $(document).on('change','#PageSize', function (e) {
        e.preventDefault();
        var page = 1;
        var pagesize = $("#PageSize").val();
        var q = $("#q").val();
        $.ajax({
            url: '@Url.Action("IndexAjax", "Materials", new { Area = "TenantManage" })',
            data: { q: q, pagesize: pagesize, page: page },
            type: 'post',
            datatype: "json",
            success: function (data) {
                $('#tablecontainer').html(data);
               // toastr.success('Pager has been changed', "Success!");
            },
            error: function (jqXHR, exception) {
                ShowErrorMessage(jqXHR, exception);
            }
        });  
    });
});    
 0
Author: Miroslav Siska,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-01-23 22:44:54

Zgadzam się z @going 's odpowiedź. Innym podobnym rozwiązaniem, które zadziałało dla mnie jest to poniżej. Jedyną różnicą jest to, że używam .on ("wejście"...) zamiast keyup. To tylko przechwytuje zmiany w danych wejściowych. inne klawisze, takie jak Ctrl, Shift itp. są ignorowane

var typingTimer;                //timer identifier
var doneTypingInterval = 5000;  //time in ms (5 seconds)

//on input change, start the countdown

$('#myInput').on("input", function() {    
    clearTimeout(typingTimer);
    typingTimer = setTimeout(function(){
        // doSomething...
    }, doneTypingInterval);
});
 0
Author: Grace.io,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-03-15 09:39:19

Dlaczego po prostu nie użyć onfocusout?

Https://www.w3schools.com/jsreF/event_onfocusout.asp

Jeśli jest to Formularz, zawsze opuszczą fokus każdego pola wejściowego, aby kliknąć przycisk Wyślij, więc wiesz, że żadne wejście nie przegapi wywołania obsługi zdarzenia onfocusout.

 0
Author: coffeeeee,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-08-28 23:47:41

Właśnie wymyśliłem prosty kod, aby czekać, aż Użytkownik skończy pisać:

Krok 1.Ustaw time out na null, a następnie wyczyść bieżący limit czasu podczas wpisywania przez użytkownika.

Krok 2.WYZWALACZ clear timeout do zmiennej define przed wywołaniem zdarzenia keyup. Krok 3.define timeout do zmiennej zadeklarowanej powyżej;
<input type="text" id="input" placeholder="please type" style="padding-left:20px;"/>
<div class="data"></div>

Kod Javascript

var textInput = document.getElementById('input');
var textdata = document.querySelector('.data');
// Init a timeout variable to be used below
var timefired = null;

// Listen for keystroke events
// Init a timeout variable to be used below
var timefired = null;// Listen for keystroke events
textInput.onkeyup = function (event) {
clearTimeout(timefired);
timefired = setTimeout(function () {
    textdata.innerHTML = 'Input Value:'+ textInput.value;
  }, 600);
};
 0
Author: Nevil Saul Blemuss,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-02-09 00:53:29

Wow, nawet 3 komentarze są całkiem poprawne!

  1. Puste wejście nie jest powodem do pominięcia wywołania funkcji, np. usuwam parametr waste z url przed przekierowaniem

  2. .on ('input', function() { ... }); należy użyć do wyzwalania keyup, paste i change zdarzenia

  3. Zdecydowanie .val() lub .value należy użyć

  4. Możesz użyć $(this) wewnątrz funkcji zdarzenia zamiast #id do pracy z wieloma wejściami

  5. (moja decyzja) używam anonimowych funkcja zamiast doneTyping W setTimeout aby łatwo uzyskać dostęp $(this) z n. 4, ale najpierw musisz ją zapisać jak var $currentInput = $(this);

 -1
Author: vladkras,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-08-14 13:32:35