2013-02-01 13 views
10

Desidero attivare un'azione ajax quando l'utente effettua una pausa durante la digitazione (anziché dopo ogni pressione di un tasto). Così ho fatto qualcosa del genere:Timeout JavaScript si attiva 3 volte invece di una volta (clearTimeout non funziona?)

Quando l'utente smette di digitare dopo 3 secondi di inattività, la funzione deve essere eseguita ... (è - ma perché 3 volte per le frasi lunghe - mi aspetto che funzioni solo una volta da quando ho cancellato il timeout dopo ogni keydown). Qual è il problema ?

var timer; 
var interval = 3000; 
$('#inp').keyup(function() { 
    timer = setTimeout(done, interval); 
}); 

$('#inp').keydown(function() { 
    clearTimeout(timer) 
}); 

function done() { 
    console.log('ajax'); 
} 

esempio Lavorando su jsfiddle: http://jsfiddle.net/vtwVH/

+1

http://stackoverflow.com/questions/1909441/jquery- keyup ritardo –

risposta

7

Il problema è che si sta sovrascrivendo la variabile timer nel vostro evento KeyDown.

Quindi, se si preme un altro tasto prima che il Timout viene cancellata per esempio tenere premuto un tasto

Il riferimento al timeout è persa e non è possibile cancellarlo di nuovo.

Per risolvere questo problema è possibile solo chiaro e impostare il timer in caso keyUp come

var timer; 
var interval = 3000; 


$('#inp').keyup(function(e){ 
    if(timer) { 
     clearTimeout(timer); 
    } 
    timer = setTimeout(done, interval); 

}); 

function done() { 
    console.log('ajax'); 
} 

Heres un lavoro fiddle

9

Quando si digita, si può a volte premere un altro tasto prima di rilasciare il primo. Potresti non accorgertene, soprattutto se stai scrivendo una lunga frase. In tal caso, l'ordine degli eventi non è down up down up ma down down up up, quindi verranno impostati due timeout.

È più coerente cancellare il timeout appena prima di impostarlo (nello stesso gestore eventi).

0

solo assicurarsi di chiara l'intervallo:

var timer; 
var interval = 3000; 


$('#inp').keyup(function(){ 
    clearTimeout(timer) 
    timer = setTimeout(done, interval); 
}); 

$('#inp').keydown(function(){ 
    clearTimeout(timer) 
}); 

function done() { 
    console.log('ajax'); 
} 

JSFiddle

1

Gli eventi sembrano non seguire le regole sequenziali rigorose, secondo keydown viene prima del primo keyup, quindi il timer viene inizializzato più volte.

Prova questo mod:

$('#inp').keyup(function(){ 
    clearTimeout(timer); 
    timer = setTimeout(done, interval); 
}); 
0

A meno che l'utente digita molto lento, il keydown e keyup non verrà nell'ordine in cui pensi. Ad esempio, è possibile ottenere due eventi keydown seguiti da due eventi keyup. Se non lo gestisci, il secondo evento keyup avvierà un altro timer e sovrascriverà il riferimento al primo timer in modo che non venga cancellato.

monitorare se il timeout è in esecuzione, e chiaro in keyup se è in esecuzione:

var timer = null; 
var interval = 3000; 
$('#inp').keyup(function(){ 
    if (timer != null) { 
    window.clearTimeout(timer) 
    } 
    timer = window.setTimeout(done, interval); 
}); 

$('#inp').keydown(function(){ 
    if (timer != null) { 
    window.clearTimeout(timer); 
    timer = null; 
    } 
}); 

function done() { 
    timer = null; 
    console.log('ajax'); 
} 

Demo: http://jsfiddle.net/Guffa/vtwVH/3/

Problemi correlati