Quiero activar un evento justo después de dejar de escribir (no mientras escribo) caracteres en mi cuadro de texto de entrada.
Lo he probado con:
$('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);
});
Pero este ejemplo produce un tiempo de espera para cada carácter escrito y obtengo alrededor de 20 solicitudes AJAX si escribo 20 caracteres.
En este violín demuestro el mismo problema con una alerta simple en lugar de un AJAX.
¿Existe una solución para esto o simplemente estoy usando un mal enfoque para esto?
Respuestas:
Tendrá que usar un
setTimeout
(como usted) pero también almacenar la referencia para que pueda seguir restableciendo el límite. Algo como:// // $('#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>
Eso se ejecutará cuando:
blur
evento)(Lo que sea que venga primero)
fuente
keyup
funciona. Es posible que desee inspeccionar esto y modificar el código de forma adecuada.paste
-$el.is(':input') && $el.on('keyup keypress paste',function(e){
SOLUCIÓN:
Aqui esta la solucion. Ejecutar una función después de que el usuario ha dejado de escribir durante un período de tiempo específico:
var delay = (function(){ var timer = 0; return function(callback, ms){ clearTimeout (timer); timer = setTimeout(callback, ms); }; })();
Uso
$('input').keyup(function() { delay(function(){ alert('Hi, func called'); }, 1000 ); });
fuente
Puede usar underscore.js "debounce"
$('input#username').keypress( _.debounce( function(){<your ajax call here>}, 500 ) );
Esto significa que su llamada de función se ejecutará después de 500 ms de presionar una tecla. Pero si presiona otra tecla (se dispara otro evento de pulsación de tecla) antes de los 500 ms, la ejecución de la función anterior se ignorará (supresión de rebotes) y la nueva se ejecutará después de un nuevo temporizador de 500 ms.
Para obtener información adicional, usar _.debounce (func, timer, true ) significaría que la primera función se ejecutará y todos los demás eventos de pulsación de teclas dentro de los siguientes temporizadores de 500ms serían ignorados.
fuente
¡Necesitas antirrebote!
Aquí hay un complemento de jQuery , y aquí está todo lo que necesita saber sobre debounce . Si viene aquí desde Google y Subrayado ha encontrado su camino en la JSoup de su aplicación, tiene antirrebote al horno justo en !
fuente
solución limpia:
$.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; };
fuente
Debe asignar
setTimeout
una variable y usarlaclearTimeout
para borrarla al presionar una tecla.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 });
Violín
Espero que esto ayude.
fuente
Hay un complemento simple que hice que hace exactamente eso. Requiere mucho menos código que las soluciones propuestas y es muy ligero (~ 0,6kb)
Primero crea un
Bid
objeto que puede ser enbumped
cualquier momento. Cada golpe retrasará la activación de la devolución de llamada de oferta para la próxima cantidad de tiempo determinada.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
Cuando el
Bid
objeto está listo, lo necesitamos debump
alguna manera. Adjuntemos golpes akeyup
event
.$("input").keyup(function(){ searchBid.bump( $(this).val() ); //parameters passed to bump will be accessable in Bid callback });
Lo que pasa aquí es:
Cada vez que el usuario presiona la tecla, la oferta se 'retrasa' (golpea) durante los siguientes 200 ms. Si transcurren 200 ms sin que vuelva a sonar "golpeado", se activará la devolución de llamada.
Además, tiene 2 funciones adicionales para detener la oferta (si el usuario presionó esc o hizo clic en una entrada externa, por ejemplo) y para finalizar y activar la devolución de llamada inmediatamente (por ejemplo, cuando el usuario presiona la tecla Intro):
searchBid.stop(); searchBid.finish(valueToPass);
fuente
He estado buscando un código HTML / JS simple y no encontré ninguno. Luego, escribí el siguiente código usando
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>
fuente
¿Por qué hacer tanto cuando solo quieres reiniciar un reloj?
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); });
si está trabajando en wordpress, entonces necesita envolver todo este código dentro de un bloque 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); }); });
fuente
Utilice el atributo onkeyup = "myFunction ()" en el
<input>
de su html.fuente
En mi opinión, un usuario deja de escribir cuando no se concentra en esa entrada. Para esto tienes una función llamada "desenfoque" que hace cosas como
fuente