javascript - detectar - keypress jquery ejemplos
¿Ejecutar la función javascript cuando el usuario termina de escribir en lugar de en la tecla arriba? (22)
¿Por qué no usar onfocusout?
https://www.w3schools.com/jsreF/event_onfocusout.asp
Si se trata de un formulario, siempre dejarán el foco de cada campo de entrada para hacer clic en el botón de envío, de modo que sepa que ninguna entrada se perderá cuando se llame al controlador de eventos onfocusout.
Quiero activar una solicitud de ajax cuando el usuario haya terminado de escribir en un cuadro de texto. No quiero que ejecute la función cada vez que el usuario escribe una letra porque eso daría lugar a MUCHAS solicitudes de ajax, pero tampoco quiero que tengan que presionar el botón Intro.
¿Hay alguna forma de poder detectar cuándo el usuario ha terminado de escribir y luego hacer la solicitud de ajax?
Usando jQuery aquí! Dave
Acabo de descubrir un código simple para esperar a que el usuario termine de escribir:
el paso 1. configura el tiempo de espera en nulo y borra el tiempo de espera actual cuando el usuario está escribiendo.
paso 2. desencadenar el tiempo de espera de eliminación de la variable definir antes de que se active el evento keyup.
paso 3. define el tiempo de espera para la variable declarada anteriormente;
<input type="text" id="input" placeholder="please type" style="padding-left:20px;"/>
<div class="data"></div>
código 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);
};
Bueno, estrictamente hablando, no, ya que la computadora no puede adivinar cuando el usuario ha terminado de escribir. Por supuesto, puede activar un temporizador con la tecla arriba y reiniciarlo con cada tecla posterior. Si el temporizador caduca, el usuario no ha escrito durante la duración del temporizador; puede llamar a eso "terminado de escribir".
Si espera que los usuarios hagan pausas mientras escriben, no hay forma de saber cuándo se realizan.
(A menos que, por supuesto, pueda deducir de los datos cuando estén listos)
De acuerdo con la respuesta de @going. Otra solución similar que funcionó para mí es la siguiente. La única diferencia es que estoy usando .on ("input" ...) en lugar de keyup. Esto solo captura los cambios en la entrada. otras teclas como Ctrl, Shift, etc. son ignoradas
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);
});
Entonces, voy a adivinar que terminar de escribir significa que simplemente te detienes por un tiempo, digamos 5 segundos. Así que con eso en mente, comencemos un temporizador cuando el usuario suelta una tecla y la borra cuando presiona una. Decidí que la entrada en cuestión será #myInput.
Haciendo algunas suposiciones ...
//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
}
Es solo una línea con la función de rebote underscore.js :
$(''#my-input-box'').keyup(_.debounce(doSomething , 500));
Esto básicamente dice doSomething 500 milisegundos después de que deje de escribir.
Para más información: http://underscorejs.org/#debounce
Este es el código JS simple que escribí:
<!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>
La respuesta elegida anteriormente no funciona.
Debido a que, ocasionalmente, typingTimer se configura varias veces (si se pulsa la tecla dos veces antes de que se active el tecleado para tipificadores rápidos, etc.), no se borra correctamente.
La solución a continuación resuelve este problema y llamará X segundos después de que termine, según lo solicitado por el OP. También ya no requiere la función de reducción de teclado redundante. También agregué un cheque para que su llamada de función no ocurra si su entrada está vacía.
//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
}
Y el mismo código en la solución JavaScript de vainilla:
//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
}
Esta solución usa ES6 pero no es necesario aquí. Simplemente reemplace let
con var
y la función de flecha con una función regular.
Las dos mejores respuestas no funcionan para mí. Entonces, aquí está mi solución:
var timeout = null;
$(''#myInput'').keyup(function() {
clearTimeout(timeout);
timeout = setTimeout(function() {
//do stuff here
}, 500);
});
Me gusta la respuesta de Surreal Dream, pero descubrí que mi función "doneTyping" se activaría con cada pulsación de tecla, es decir, si escribes "Hola" muy rápido; en lugar de disparar solo una vez cuando deja de escribir, la función dispararía 5 veces.
El problema fue que la función setTimeout de javascript no parece sobrescribir ni eliminar los tiempos de espera anteriores que se hayan establecido, pero si lo haces tú mismo, ¡funciona! Así que acabo de agregar una llamada a clearTimeout justo antes de setTimeout si se establece typingTimer. Vea abajo:
//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
}
NB Me hubiera gustado haber agregado esto como un comentario a la respuesta de Surreal Dream, pero soy un usuario nuevo y no tengo suficiente reputación. ¡Lo siento!
Modificando la respuesta aceptada para manejar casos adicionales como pegar:
//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
}
No creo que el evento keyDown sea necesario en este caso (por favor, dime por qué si estoy equivocado). En mi (no-jquery) script, la solución similar se ve así:
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)
}
}
Es mi primera respuesta en , así que espero que esto ayude a alguien, algún día :)
No estoy seguro si mis necesidades son un poco extrañas, pero necesitaba algo similar a esto y esto es lo que terminé usando:
$(''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'');
});
Lo que me permite tener elementos como este en mi aplicación:
<input type="text" data-url="/controller/action/" class="update">
Que se actualiza cuando el usuario ha "terminado de escribir" (no se realiza ninguna acción durante 2 segundos) o va a otro campo (desenfoca el elemento)
Puede usar el evento onblur para detectar cuándo el cuadro de texto pierde el foco: https://developer.mozilla.org/en/DOM/element.onblur
Eso no es lo mismo que "deja de escribir", si te preocupa el caso en el que el usuario escribe un montón de cosas y luego se sienta allí con el cuadro de texto aún enfocado.
Para eso sugeriría vincular un setTimeout al evento onclick, y suponiendo que después de x la cantidad de tiempo sin pulsar las teclas, el usuario haya dejado de escribir.
Sí, puede establecer un tiempo de espera de, por ejemplo, 2 segundos en cada evento de activación de claves que activará una solicitud ajax. También puede almacenar el método XHR y abortarlo en sucesivos eventos de pulsación de tecla para que pueda guardar aún más el ancho de banda. Aquí hay algo que he escrito para un script de autocompletar mío.
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
});
Espero que esto ayude,
Marko
SOLUCIÓN:
Estaba implementando la búsqueda en mi listado y necesito que esté basada en ajax. Eso significa que en cada cambio clave los resultados buscados deben actualizarse y mostrarse. Este trabajo da como resultado que se envíen tantas llamadas ajax al servidor, lo que no es bueno. Después de algunos trabajos hice un acercamiento al servidor de ping cuando el cliente deja de escribir.
La solución que me funcionó es:
$(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
Ha notado que no hay necesidad de usar ningún temporizador al implementar esto.
Estoy seguro, esto ayudará a otros.
Ata
Si está buscando una longitud específica (como un campo de código postal):
$("input").live("keyup", function( event ){
if(this.value.length == this.getAttribute(''maxlength'')) {
//make ajax request here after.
}
});
Si necesita esperar hasta que el usuario termine de escribir, use esto:
$(document).on(''change'',''#PageSize'', function () {
//Do something after new value in #PageSize
});
Ejemplo completo con llamada ajax - esto funciona para mi buscapersonas - recuento de elementos por lista:
$(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);
}
});
});
});
Siento que la solución es un poco más simple con el evento de input
:
var typingTimer;
var doneTypingInterval = 500;
$("#myInput").on("input", function () {
window.clearTimeout(typingTimer);
typingTimer = window.setTimeout(doneTyping, doneTypingInterval);
});
function doneTyping () {
// code here
}
Una vez que detecte el foco en el cuadro de texto, en la tecla de arriba haga una verificación de tiempo de espera y reinícielo cada vez que se active.
Cuando se agote el tiempo de espera, haga su solicitud de ajax.
Wow, incluso 3 comentarios son bastante correctos!
La entrada vacía no es una razón para omitir la llamada a la función, por ejemplo, elimino el parámetro de residuos de la URL antes de redirigir
.on (''input'', function() { ... });
debe ser utilizado para activarkeyup
,paste
ychange
definitivamente se debe usar
.val()
o.value
Puede usar
$(this)
dentro de la función de evento en lugar de#id
para trabajar con múltiples entradas(mi decisión) uso la función anónima en lugar de
doneTyping
ensetTimeout
para acceder fácilmente a$(this)
desde n.4, pero primero debes guardarlo comovar $currentInput = $(this);
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);
}
});
Ejemplo completo aquí: http://jsfiddle.net/ZYXp4/8/