2013-07-26 19 views
7

Nonostante molti articoli su SO su come simulare le pressioni dei tasti (keydown/keypress) in JS, nessuna soluzione sembra funzionare con i browser che sto utilizzando (Firefox ESR 17.0. 7, Chrome 28.0.1500.72, IE 10). Le soluzioni che ho testato sono state prese da here, here e here.JavaScript: Simula eventi chiave in Textbox/Input

Quello che sto cercando di fare è simulare QUALSIASI battitura in una textarea/input. Mentre posso aggiungere/eliminare caratteri cambiando direttamente "valore", non vedo alcuna opzione se non la simulazione di input per i tasti come "Su", "Giù", "Casa" e alcuni altri.

Secondo lo documentation, dovrebbe essere semplice. Ad esempio:

var e = document.createEvent("KeyboardEvent"); 
if (e.initKeyboardEvent) { // Chrome, IE 
    e.initKeyboardEvent("keydown", true, true, document.defaultView, "Enter", 0, "", false, ""); 
} else { // FF 
    e.initKeyEvent("keydown", true, true, document.defaultView, false, false, false, false, 13, 0); 
} 
document.getElementById("text").dispatchEvent(e); 

infatti attiva l'evento "Invio" keydown e il gestore può prenderlo. Tuttavia, non influenza in alcun modo la textarea - una nuova riga non appare. Lo stesso vale per altri codici: i caratteri non compaiono, le frecce non cambiano la posizione del cursore, ecc.

Ho esteso il codice di Orwellophile e lo ho postato su http://jsfiddle.net/npF3d/4/, in modo che chiunque possa giocare con il codice. Nei miei browser, nessun pulsante produce alcun effetto sulla textarea in nessuna condizione.

Apprezzerei qualsiasi aiuto su questo problema.

risposta

6

Sono abbastanza certo che si tratta di una cosa di "sicurezza", poiché mi sono imbattuto nella stessa cosa quando provavo a simulare le pressioni dei tasti prima.

Q: Come posso digitare in modo programmatico allora?
A: Ottenere/impostazione selectionStart, selectionEnd, ecc, così come l'utilizzo di questi in combinazione con String metodi come slice per inserire caratteri. (Vedi riferimento HTMLTextAreaElement)

D: Perché dovresti continuare a utilizzare questo tipo di evento?
A: Tutti gli ascoltatori di eventi funzioneranno come se fosse un vero evento chiave.


funzionalità ridotta per le frecce/home/fine può essere raggiunto questa convenzione DEMO

function homeKey(elm) { 
    elm.selectionEnd = 
     elm.selectionStart = 
      elm.value.lastIndexOf(
       '\n', 
       elm.selectionEnd - 1 
      ) + 1; 
} 

function endKey(elm) { 
    var pos = elm.selectionEnd, 
     i = elm.value.indexOf('\n', pos); 
    if (i === -1) i = elm.value.length; 
    elm.selectionStart = elm.selectionEnd = i; 
} 

function arrowLeft(elm) { 
    elm.selectionStart = elm.selectionEnd -= 1; 
} 

function arrowRight(elm) { 
    elm.selectionStart = elm.selectionEnd += 1; 
} 

function arrowDown(elm) { 
    var pos = elm.selectionEnd, 
     prevLine = elm.value.lastIndexOf('\n', pos), 
     nextLine = elm.value.indexOf('\n', pos + 1); 
    if (nextLine === -1) return; 
    pos = pos - prevLine; 
    elm.selectionStart = elm.selectionEnd = nextLine + pos; 
} 

function arrowUp(elm) { 
    var pos = elm.selectionEnd, 
     prevLine = elm.value.lastIndexOf('\n', pos), 
     TwoBLine = elm.value.lastIndexOf('\n', prevLine - 1); 
    if (prevLine === -1) return; 
    pos = pos - prevLine; 
    elm.selectionStart = elm.selectionEnd = TwoBLine + pos; 
} 

D: Dove va a finire male?
A: Se le linee sono lunghe abbastanza da essere avvolte, le tratteranno come se fossero state scartate.

+0

OK, ho avuto la stessa sensazione che questo potrebbe essere fatto intenzionalmente per motivi di sicurezza. A partire da Q/A: la modifica del testo non è un problema, il problema è simulare "Su", "Giù", "Casa" e simili ... – lexasss

+0

quelli che potrebbero essere implementati se si ricrea la textarea/input come nodo di blocco contenente i nodi inline per ogni carattere con wrapping, dimensioni e styling corrispondenti, quindi calcolando tutte le diverse rects per trovare dove si desidera finire. Non riesco a immaginare che sia facile da implementare ... forse un modo più semplice sarebbe usare un font monospace, capire dove era il precedente carattere della nuova riga e poi contare i caratteri. –

+0

Grazie. Tuttavia, simulo l'input su terze pagine, come google.com. La mia tastiera virtuale è implementata come estensione di Chrome e deve essere in grado di consentire agli utenti di digitare e modificare il testo nei moduli su qualsiasi pagina utilizzando solo questa tastiera. Sarebbe una grande delusione se alcune funzionalità dovessero essere abbandonate. – lexasss

0

Invio di chiavi per il browser può essere raggiunto tramite Selenio: http://docs.seleniumhq.org/

Esso fornisce un driver per ogni browser che può essere programmato. Di solito inizia con l'apertura di un URL, quindi il tuo script fungerà da telecomando per il browser. In questo modo è possibile inviare le chiavi effettive anziché simularle, il che non è possibile in modo programmatico all'interno del browser.

Si potrebbe per esempio ottenere questo usando http://webdriver.io/