2010-02-20 8 views
11

Questo mi sta facendo impazzire. È difficile da spiegare ma ci provo.Ho problemi con l'evento keydown e completamento automatico in Firefox su mac

Ho un campo di testo di input sulla prima pagina del mio sito. Ho codificato un osservatore di eventi keydown che controlla il keyCode e se è ENTER (o equiv), controlla il valore di input (email). Se l'e-mail è valida e unica nel DB, verrà inviato il modulo. Roba di base, o così si potrebbe pensare.

Se digito il mio indirizzo e-mail nel campo e premo invio, funziona perfettamente con tutti i browser. Tuttavia, se digito la prima coppia di lettere, e poi usare i tasti freccia per selezionare l'e-mail dalla casella a discesa della cronologia (spero tu sappia cosa intendo qui), e quindi premi invio il risultato è diverso. Il valore del campo modulo viene catturato come solo la coppia di lettere che ho digitato, e quindi la validazione sta fallendo. Sembra che quando premo il tasto Invio per "selezionare" l'e-mail dal menu a discesa della cronologia, il browser lo interrompe come se stessi scrivendo.

In Chrome e Safari funziona come dovrebbe. Come dovrebbe significare che quando si preme Invio per "selezionare" l'e-mail dal menu a discesa della cronologia, tutto ciò che fa è mettere quell'indirizzo e-mail nella casella di testo. Solo premendo il secondo tasto INVIO, viene attivato l'osservatore dell'evento e l'e-mail viene convalidata.

Spero che qualcuno possa far luce sul perché questo sta accadendo ... Il mio istinto è una cosa da browser e sarà qualcosa che non posso aggiustare.

Grazie Lee

EDIT: Per aggiungere un chiarimento alla mia domanda mi permetta di aggiungere che Im utilizzando l'evento "KeyDown" per catturare il momento in cui viene premuto il tasto Invio. Ho provato l'evento "keyup" e questo ha risolto il mio problema sopra, ma poi non riesco a fermare il modulo che presenta da solo. L'evento "keyup" si attiva dopo il comportamento predefinito, quindi non è la scelta giusta per questo.

ULTERIORI EDIT:

Grazie ancora, e btw, il tuo inglese è eccellente (in risposta al tuo commento su Bad English).

ho cambiato il mio gestore di eventi da questo:

$("emailInputBox").observe("keydown", function(event) { 
    return submitViaEnter(event, submitSignupFormOne); 
}); 

a questo:

$("emailInputBox").observe("keydown", function(event) { 
    setTimeout(submitViaEnter.curry(event, submitSignupFormOne),0); 
}); 

submitViaEnter:

function submitViaEnter(event, callback) { 
var code = event.keyCode; 
if (code == Event.KEY_RETURN) { 
    event.stop(); 
    return callback(event); 
} 
return true; 
} 

sembra funzionare, ma il problema ora è che il browser è consentito eseguire l'azione predefinita prima di eseguire lo submitViaEnter funzione che significa che il modulo viene inviato quando premo INVIO.

risposta

6

risposta alla domanda iniziale

Sì, è un bug Gecko (non Mac-specifica però).

The last part of this comment contiene la descrizione del work-around: utilizzare il timeout.

[modifica] dal momento che hai chiesto per la chiarificazione del bug

Quando si preme Invio e il completamento automatico è attiva, Firefox (erroneamente) prima spara di gestione dei tasti della pagina, quindi il tasto interno del browser gestore che chiude il popup di completamento automatico e aggiorna il valore dell'area di testo, mentre probabilmente dovrebbe semplicemente aprirlo al popup di completamento automatico e solo lasciare che la pagina conosca il valore della casella di testo cambiata.

Ciò significa che quando viene chiamato il gestore di chiavi, il gestore del completamento automatico non è ancora in esecuzione - il popup di completamento automatico è ancora aperto e il valore della casella di testo è come se fosse appena prima del completamento automatico.

Quando aggiungi una chiamata setTimeout al tuo gestore di chiavi, stai dicendo al browser "hey, esegui questa funzione subito dopo aver finito di fare cose già nella tua lista di cose da fare in P1". Quindi il gestore del completamento automatico viene eseguito, poiché è già presente nell'elenco delle cose da fare, quindi viene eseguito il codice inserito in un timeout, quando il popup del completamento automatico è già chiuso e il valore della casella di testo viene aggiornato.

[modifica] rispondendo alla domanda nella sezione "Ulteriori modifica"

destro. È necessario annullare l'azione predefinita nel gestore di eventi, non nel timeout, se si desidera farlo funzionare:

function onKeyPress(ev) { 
    if (... enter pressed ...) { 
    setTimeout(function() { 
     ... check the new textbox value after letting autocomplete work ... 
    }, 0); 
    // but cancel the default behavior (submitting the form) directly in the event listener 
    ev.preventDefault(); 
    return false; 
    } 
} 

Se ancora voleva inviare il modulo su Invio, sarebbe un esercizio più interessante, ma non sembra che tu lo faccia.

+0

Grazie !! Ive ha lavorato intorno disabilitando la funzionalità di completamento automatico per il modulo, ma non mi piace. Sai cos'è "il time-out" e, in caso affermativo, puoi elaborare per favore? Grazie ancora. –

+0

@LeeRM: nella chiamata al gestore di keydown setTimeout (handler2, 0) e sposta il codice di convalida in | function handler2() {} |. – Nickolay

+0

oh capisco. Mi dispiace se sono spesso qui. Proprio quando penso che sto diventando bravo in questa roba ... Qual è il risultato di questo? So che risolve il problema che sto avendo ma come? Mi piace capire cosa sta succedendo. Grazie per l'aiuto! –

2

ok ordinato. Grazie mille per il vostro aiuto. Era la funzione di curry che mi mancava prima. Stavo cercando di lavorare sull'evento nell'ambito della funzione setTimeout.

Questo funziona di seguito. Il submitViaEnter è chiamato dal eventobserver e risponde all'evento keyDown:

function submitViaEnter(event, callback) { 
var code = event.keyCode; 
if (code == Event.KEY_RETURN) { 
    event.stop(); 
    setTimeout(callback.curry(event),0);   
    // return callback(event); 
    // return false;  
} 
return true; 
} 

Fermare l'azione predefinita all'interno della eventObserver significava che nessun carattere potrebbero essere digitati. Quindi mi sono bloccato all'interno della clausola se INVIO.

Problemi correlati