2013-07-26 40 views
7

Pomimo wielu artykułów na temat SO na temat symulacji naciśnięć klawiszy (keydown/keypress) w JS, żadne rozwiązanie nie działa z przeglądarkami, których używam (Firefox ESR 17.0. 7, Chrome 28.0.1500.72, IE 10). Rozwiązania, które testowałem zostały zaczerpnięte z here, here i here.JavaScript: Symulowanie kluczowych zdarzeń w polu tekstowym/wprowadzeniu

Co próbuję zrobić, to zasymulować JAKIKOLWIEK naciśnięcie klawisza w polu tekstowym/wprowadzeniu. Chociaż mogę dodawać/usuwać znaki bezpośrednio zmieniające "wartość", nie widzę opcji, oprócz symulacji wejścia dla klawiszy takich jak "Up", "Down", "Home" i kilka innych.

Zgodnie z documentation, powinno być proste. Na przykład:

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); 

rzeczywiście odpala zdarzenie klucza "Enter", a mój przewodnik może go złapać. Nie wpływa to jednak w żaden sposób na tekst - nowy wiersz się nie pojawia. To samo dotyczy innych kodów klawiszy: znaki nie pojawiają się, strzałki nie zmieniają położenia karetki, itp.

Poszerzyłem kod o Orwellophile i wysłałem go pod numer http://jsfiddle.net/npF3d/4/, aby każdy mógł grać z kodem. W moich przeglądarkach żaden przycisk nie powoduje żadnego efektu na obszarze tekstowym w żadnych warunkach.

Byłbym wdzięczny za pomoc w tej sprawie.

Odpowiedz

6

Jestem prawie pewien, że jest to kwestia "bezpieczeństwa", ponieważ napotkałem na to samo, próbując zasymulować naciśnięcia klawiszy.

P: Jak mogę programowo wpisać?
A: Pierwsze/ustawienia SelectionStart, selectionEnd, itp, a także stosując je w połączeniu z String metod jak slice wstawić znaki. (Patrz odniesienie HTMLTextAreaElement)

P: Dlaczego więc nadal korzystasz z tego rodzaju wydarzeń?
O: Wszystkie detektory zdarzeń będą działać tak, jakby były prawdziwym kluczowym wydarzeniem.


Ograniczona funkcjonalność dla strzałki/home/koniec można osiągnąć thusly 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; 
} 

Q: Gdzie to się nie udać?
O: Jeśli linie są wystarczająco długie, aby je zawijać, będą traktować je jako nieopakowane.

+0

OK, miałem to samo uczucie, że może to być zrobione celowo ze względów bezpieczeństwa. Od Q/A: edycja tekstu nie stanowi problemu, problem polega na symulacji "Up", "Down", "Home" i tym podobnych ... – lexasss

+0

te mogą zostać zaimplementowane po odtworzeniu textarea/input jako węzeł blokowy zawierający wbudowane węzły dla każdego znaku z dopasowanym zawijaniem, wielkością i stylem, a następnie obliczanie wszystkich różnych rectów, aby znaleźć miejsce, w którym chcesz skończyć. Nie mogę sobie wyobrazić, że jest to łatwe do wdrożenia ... być może lepszym sposobem byłoby użycie czcionki o stałej szerokości, sprawdzanie, gdzie był poprzedni znak nowej linii, a następnie liczenie znaków. –

+0

Dzięki. Jednak symuluję dane wejściowe na trzecich stronach, takich jak google.com. Moja wirtualna klawiatura jest zaimplementowana jako rozszerzenie Chrome i musi umożliwiać użytkownikom wpisywanie i modyfikowanie tekstu w formularzach na dowolnej stronie przy użyciu tylko tej klawiatury. Byłoby wielkim rozczarowaniem, gdyby niektóre funkcje zostały usunięte. – lexasss

0

Wysyłanie klucze do przeglądarki można osiągnąć poprzez Selen: http://docs.seleniumhq.org/

Zapewnia sterownik dla każdej przeglądarki, które mogą być zaprogramowane. Zwykle zaczyna się od otwarcia adresu URL, więc skrypt będzie działał jako pilot do przeglądarki. Umożliwia to wysyłanie rzeczywistych kluczy, zamiast ich symulowania, co nie jest możliwe programowo w przeglądarce.

Można na przykład osiągnąć to za pomocą http://webdriver.io/