Chcę wywołać zdarzenie zaraz po tym, jak przestanę wpisywać (nie podczas wpisywania) znaków w moim polu tekstowym.
Próbowałem z:
$('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);
});
Ale ten przykład generuje limit czasu dla każdego wpisanego znaku i otrzymuję około 20 żądań AJAX, jeśli wpiszę 20 znaków.
Na tych skrzypcach pokazuję ten sam problem za pomocą prostego alertu zamiast AJAX.
Czy jest na to rozwiązanie, czy po prostu używam złego podejścia?
Odpowiedzi:
Będziesz musiał użyć
setTimeout
(tak jak jesteś), ale także zapisać odniesienie, aby móc resetować limit. Coś jak:// // $('#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>
To się wykona, gdy:
blur
zdarzenie)(Cokolwiek będzie pierwsze)
źródło
keyup
działa. Możesz chcieć to sprawdzić i odpowiednio zmodyfikować kod.paste
-$el.is(':input') && $el.on('keyup keypress paste',function(e){
ROZWIĄZANIE:
Oto rozwiązanie. Wykonywanie funkcji po tym, jak użytkownik przestał pisać przez określony czas:
var delay = (function(){ var timer = 0; return function(callback, ms){ clearTimeout (timer); timer = setTimeout(callback, ms); }; })();
Stosowanie
$('input').keyup(function() { delay(function(){ alert('Hi, func called'); }, 1000 ); });
źródło
Możesz użyć underscore.js „debounce”
$('input#username').keypress( _.debounce( function(){<your ajax call here>}, 500 ) );
Oznacza to, że wywołanie funkcji zostanie wykonane po 500 ms od naciśnięcia klawisza. Ale jeśli naciśniesz inny klawisz (zostanie uruchomione kolejne zdarzenie naciśnięcia klawisza) przed 500 ms, poprzednie wykonanie funkcji zostanie zignorowane (usunięte), a nowa zostanie wykonana po nowym liczniku czasu 500 ms.
Aby uzyskać dodatkowe informacje, użycie _.debounce (func, timer, true ) oznaczałoby, że pierwsza funkcja zostanie wykonana, a wszystkie inne zdarzenia naciśnięcia klawisza z kolejnymi licznikami czasu 500 ms byłyby ignorowane.
źródło
Potrzebujesz odbicia!
Oto wtyczka jQuery i wszystko, co musisz wiedzieć o debounce . Jeżeli przyjeżdżasz tu z Google i podkreślenia znalazła swoją drogę do JSoup swojej aplikacji, ma ZWLOKA pieczone w prawo !
źródło
oczyszczony roztwór:
$.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; };
źródło
Powinieneś przypisać
setTimeout
do zmiennej i użyć,clearTimeout
aby wyczyścić ją po naciśnięciu klawisza.var timer = ''; $('input#username').keypress(function() { clearTimeout(timer); timer = setTimeout(function() { //Your code here }, 3000); //Waits for 3 seconds after last keypress to execute the above lines of code });
Skrzypce
Mam nadzieję że to pomoże.
źródło
Jest kilka prostych wtyczek , które stworzyłem, które dokładnie to robią. Wymaga znacznie mniej kodu niż proponowane rozwiązania i jest bardzo lekki (~ 0,6kb)
Najpierw tworzysz
Bid
obiekt niżbumped
kiedykolwiek. Każde uderzenie opóźni wywołanie zwrotnej oferty na następny podany czas.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
Gdy
Bid
obiekt jest gotowy,bump
jakoś tego potrzebujemy . Dołączmy do tego wpadaniekeyup
event
.$("input").keyup(function(){ searchBid.bump( $(this).val() ); //parameters passed to bump will be accessable in Bid callback });
Oto co się tutaj dzieje:
Za każdym razem, gdy użytkownik naciśnie klawisz, oferta jest „opóźniana” (zderzana) o następne 200 ms. Jeśli minie 200 ms bez ponownego `` uderzenia '', zostanie wywołany callback.
Ponadto masz 2 dodatkowe funkcje do zatrzymywania oferty (na przykład, jeśli użytkownik naciśnie klawisz esc lub kliknie zewnętrzne wejście) oraz do natychmiastowego zakończenia i wywołania wywołania zwrotnego (na przykład, gdy użytkownik naciśnie klawisz Enter):
searchBid.stop(); searchBid.finish(valueToPass);
źródło
Szukałem prostego kodu HTML / JS i nie znalazłem żadnego. Następnie napisałem poniższy kod za pomocą
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>
źródło
po co tak dużo robić, skoro po prostu chcesz zresetować zegar?
var clockResetIndex = 0 ; // this is the input we are tracking var tarGetInput = $('input#username'); tarGetInput.on( 'keyup keypress paste' , ()=>{ // reset any privious clock: if (clockResetIndex !== 0) clearTimeout(clockResetIndex); // set a new clock ( timeout ) clockResetIndex = setTimeout(() => { // your code goes here : console.log( new Date() , tarGetInput.val()) }, 1000); });
jeśli pracujesz na wordpressie, musisz zawinąć cały ten kod wewnątrz bloku jQuery:
jQuery(document).ready(($) => { /** * @name 'navSearch' * @version 1.0 * Created on: 2018-08-28 17:59:31 * GMT+0530 (India Standard Time) * @author : ... * @description .... */ var clockResetIndex = 0 ; // this is the input we are tracking var tarGetInput = $('input#username'); tarGetInput.on( 'keyup keypress paste' , ()=>{ // reset any privious clock: if (clockResetIndex !== 0) clearTimeout(clockResetIndex); // set a new clock ( timeout ) clockResetIndex = setTimeout(() => { // your code goes here : console.log( new Date() , tarGetInput.val()) }, 1000); }); });
źródło
Użyj atrybutu onkeyup = "myFunction ()" w
<input>
swoim html.źródło
Moim zdaniem użytkownik przestaje pisać, gdy nie skupia się na tym, co wpisuje. Do tego masz funkcję o nazwie "blur", która robi takie rzeczy
źródło