Je souhaite déclencher un événement juste après que j'arrête de taper (pas en cours de frappe) des caractères dans la zone de saisie.
J'ai essayé avec:
$('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);
});
Mais cet exemple produit un délai d'attente pour chaque caractère saisi et je reçois environ 20 demandes AJAX si je saisis 20 caractères.
Sur ce violon Je démontre le même problème avec une alerte simple au lieu d'un AJAX.
Y a-t-il une solution pour cela ou j'utilise simplement une mauvaise approche pour cela?
Vous devrez utiliser une variable setTimeout
(comme ce que vous êtes), mais également stocker la référence afin que vous puissiez réinitialiser la limite. Quelque chose comme:
//
// $('#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>
Cela s'exécutera quand:
blur
)(Peu importe lequel vient en premier)
SOLUTION:
Voici la solution. Exécution d'une fonction après que l'utilisateur a cessé de taper pendant un laps de temps spécifié
var delay = (function(){
var timer = 0;
return function(callback, ms){
clearTimeout (timer);
timer = setTimeout(callback, ms);
};
})();
Usage
$('input').keyup(function() {
delay(function(){
alert('Hi, func called');
}, 1000 );
});
Vous pouvez utiliser underscore.js "debounce"
$('input#username').keypress( _.debounce( function(){<your ajax call here>}, 500 ) );
Cela signifie que votre appel de fonction s’exécutera après 500 ms d’appui sur une touche. Mais si vous appuyez sur une autre touche (un autre événement de frappe est déclenché) avant les 500 ms, l'exécution de la fonction précédente sera ignorée (rebondie) et la nouvelle s'exécutera après un nouveau temporisateur de 500 ms.
Pour plus d’informations, utiliser ___bounce (func, timer, true ) signifierait que la première fonction sera exécutée et que tous les autres événements de pression de touche avec des temporisations de 500 ms seront ignorés.
Vous avez besoin de debounce!
Voici un plugin jQuery , et voici tout ce que vous devez savoir sur debounce . Si vous venez de Google et que Underscore a trouvé sa place dans le groupe JSoup de votre application, il a rebondi cuit directement dans !
solution nettoyée:
$.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;
};
Il y a de simples plugins que j'ai créés qui font exactement cela. Il nécessite beaucoup moins de code que les solutions proposées et il est très léger (~ 0,6kb)
Tout d'abord, vous créez un objet Bid
pouvant être bumped
à tout moment. Chaque bosse retardera le tir rappel pour la prochaine période donnée.
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
Lorsque l'objet Bid
est prêt, nous devons le bump
en quelque sorte. Attachons bumping à keyup
event
.
$("input").keyup(function(){
searchBid.bump( $(this).val() ); //parameters passed to bump will be accessable in Bid callback
});
Ce qui se passe ici est:
Chaque fois que l'utilisateur appuie sur la touche, l'enchère est "retardée" pendant 200 ms. Si 200 ms passent sans être à nouveau «repoussé», le rappel est déclenché.
En outre, vous disposez de 2 fonctions supplémentaires pour arrêter l'enchère (si l'utilisateur a appuyé sur la touche Echap ou que l'utilisateur a cliqué en dehors de l'entrée, par exemple) et sur la finition et le rappel immédiat (par exemple lorsque l'utilisateur a appuyé sur la touche Entrée):
searchBid.stop();
searchBid.finish(valueToPass);
Je cherchais un code HTML/JS simple et je n’en ai trouvé aucun. Ensuite, j'ai écrit le code ci-dessous en utilisant 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>
Vous devez affecter setTimeout
à une variable et utiliser clearTimeout
pour l'effacer lors de la frappe.
var timer = '';
$('input#username').keypress(function() {
clearTimeout(timer);
timer = setTimeout(function() {
//Your code here
//Your code here
}, 3000); //Waits for 3 seconds after last keypress to execute the above lines of code
});
J'espère que cela t'aides.
pourquoi faire cela quand vous voulez juste réinitialiser une horloge?
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 vous travaillez sur wordpress, vous devez insérer tout ce code à l'intérieurun bloc 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);
});
});