2009-03-31 3 views
21

Mi piacerebbe avere il browser si comporta come se l'utente avesse premuto il tasto Tab quando loro cliccano su qualcosa. Nel gestore click ho provato i seguenti approcci:Simulazione di una pressione di tasto di tabulazione usando JavaScript

var event = document.createEvent('KeyboardEvent'); 
event.initKeyEvent("keypress", true, true, null, false, false, false, false, 9, 0); 
this.input.focus()[0].dispatchEvent(event); 

e jQuery:

this.input.focus().trigger({ type : 'keypress', which : 9 }); 

... che ho preso da here.

Il primo approccio sembra essere la soluzione migliore, ma non funziona. Se cambio gli ultimi due parametri su 98, 98, infatti, una "b" viene digitata nella casella di input. Ma 9, 0 e 9, 9 (il primo dei quali ho preso direttamente dal sito web MDC) sia a me dare a questi errori in Firebug sotto FF3:

Permission denied to get property XULElement.popupOpen 
[Break on this error] this.input.focus()[0].dispatchEvent(event); 

Permission denied to get property XULElement.overrideValue 
[Break on this error] this.input.focus()[0].dispatchEvent(event); 

Permission denied to get property XULElement.selectedIndex 
[Break on this error] this.input.focus()[0].dispatchEvent(event); 

Permission denied to set property XULElement.selectedIndex 
[Break on this error] this.input.focus()[0].dispatchEvent(event); 

ho sentito tale (senza una chiara definizione di 'tali') eventi sono 'non attendibili', il che potrebbe spiegare questi errori.

Il secondo approccio causa il valore che ho messo come evento. Che deve essere passato come evento. Che, ma senza alcun effetto (anche se uso 98 anziché 9, non viene digitata "b" nella casella.) Se Provo a impostare event.data nell'oggetto che sto passando, finisce non definito quando l'evento viene attivato. Quello che segue è il codice che sto utilizzando per vedere che:

$('#hi').keypress(function(e) { 
    console.log(e); 
}); 

Altre idee?

+0

Cosa vuoi invocare? Stai cercando di spostarli al prossimo input? – hunter

+0

Sì. Ma il prossimo "input" non è necessariamente un input o un altro elemento naturalmente cancellato. Né è necessariamente innaturalmente-tabstopped (cioè, $ ("[tabindex]")). Premere fisicamente la linguetta (o shift + tab) fa esattamente quello che voglio ... – Kev

+0

Grazie per questo. Mi interessava solo il primo esempio di codice della tua domanda, il che mi ha davvero aiutato :) –

risposta

4

La soluzione con cui ho finito è creare un div "focus stealer" (con tabindex = -1 - può avere il focus ma non può essere inizialmente tablato) su entrambi i lati dell'area in cui vuoi gestire manualmente lo stato attivo. Poi metto un ascoltatore di eventi che fa bubbling per mettere a fuoco e sfocare l'intera area. Quando si verifica una messa a fuoco sull'area, i valori di tabindex vengono modificati su -1 e quando si verifica una sfocatura, vengono cambiati a 0. Ciò significa che, mentre si è concentrati nell'area, è possibile separare o disattivare la scheda e finiscono correttamente su altri elementi di pagina o elementi dell'interfaccia utente del browser, ma non appena ti concentri su di essi, i ladri di focus diventano tabbable, e sul focus impostano correttamente l'area manuale e spostano l'attenzione sull'elemento alla loro fine, come se avessi fatto clic su un'estremità o sull'altra dell'area del manuale.

1

In realtà, immagino ci sia un modo, anche se è un importante PITA. Posso assicurarmi che ogni elemento, anche se naturalmente un punto di tabulazione, abbia un Xtabindex, in qualche modo nell'ordine corretto anche se farò cadere i widget di altre persone e quindi usare jQuery per aggiungerli dopo il fatto, piuttosto che essere in grado di specificarlo direttamente nell'HTML o in altro codice di costruzione iniziale. Quindi, il mio intero modulo avrà un vero tabindex. Mentre ha il focus, assorbe i tasti premuti, e se sono tab o shift + tab, sposta il focus fasullo basato su Xtabindex. Se la scheda viene premuta sull'ultimo elemento (o Maiusc + tab sul primo) nel modulo, non ingannerà la sequenza di tasti, consentendo così al browser di focalizzare correttamente su altri elementi dell'interfaccia utente della pagina o del browser esterni al modulo utilizzando la tastiera.

Posso solo indovinare quali tipi di effetti collaterali non previsti introdurranno questo approccio.

In realtà, non è nemmeno una soluzione, perché non riesco ancora a simulare una scheda sull'ultimo elemento che lo utilizza.

+0

http: // liste .whatwg.org/htdig.cgi/whatwg-whatwg.org/2008-December/017980.html ha sollevato un punto interessante: "Ma allora cosa succederebbe se l'agente utente non facesse cose usando un ciclo, ma invece utilizzasse la gestione del fuoco direzionale , come molti telefoni? " – Kev

3

Questa è la soluzione che ho usato sulla nostra webapp per due controlli personalizzati, un calendario pop-up e un selettore di unità di peso pop-up/value (cliccando la casella di testo si apre un div con due seleziona)

function tab_focus(elem) 
    var fields = elem.form.getElements() 
    for(var i=0;i<fields.length;i++) { 
    if(fields[i].id == elem.id){ 
     for(i=i+1;i<fields.length;i++){ 
     if(fields[i].type != 'hidden'){ 
      fields[i].focus() 
      return  
     } 
     } 
     break; 
    } 
    } 
    elem.form.focusFirstElement(); 
} 

Questo sta utilizzando il framework Prototype e si aspetta un elemento esteso (ad esempio $ ('thing_id')) come parametro.

Ottiene la forma a cui appartiene l'elemento e scorre tra gli elementi del modulo fino a quando non si trova.

Quindi cerca il primo elemento che non è nascosto e passa il fuoco.

Se non ci sono elementi dopo di esso nel modulo, sposta il focus indietro sul primo elemento nel modulo. Potrei invece trovare il modulo successivo nella pagina attraverso document.forms, ma la maggior parte delle nostre pagine utilizza un unico modulo.

+0

Il fatto è che alcuni dei miei elementi dell'interfaccia utente focalizzabili non sono elementi del modulo, perché sono widget personalizzati. – Kev

+1

Per gli utenti jquery sostituire la prima riga di questa funzione con: var fields = $ ('form') [0]; Per scorrere gli elementi del modulo. – eniac

0

Penso che quegli errori derivino dal completamento automatico. Potreste essere in grado di disattivarli impostando, prima di inviare l'evento, l'attributo autocomplete 'off'

setAttribute('autocomplete','off') 
1

ho creato un simple jQuery plugin che fa risolvere questo problema. Usa il selettore ': tabbable' dell'interfaccia utente di jQuery per trovare il successivo elemento 'tabbable' e selezionarlo.

Esempio di utilizzo:

// Simulate tab key when element is clicked 
$('.myElement').bind('click', function(event){ 
    $.tabNext(); 
    return false; 
});