Ist es möglich, Tastendruckereignisse programmatisch in JavaScript zu simulieren?
Antworten
Zu viele Anzeigen?Sie können verwenden dispatchEvent()
:
function simulateKeyPress() {
var evt = document.createEvent("KeyboardEvent");
evt.initKeyboardEvent("keypress", true, true, window,
0, 0, 0, 0,
0, "e".charCodeAt(0))
var body = document.body;
var canceled = !body.dispatchEvent(evt);
if(canceled) {
// A handler called preventDefault
alert("canceled");
} else {
// None of the handlers called preventDefault
alert("not canceled");
}
}
Ich habe das nicht getestet, aber es ist an den Code auf dispatchEvent()'s Dokumentation . Lesen Sie sich das durch, und lesen Sie auch die Dokumentationen für createEvent() und initKeyEvent().
Sie können Tastaturereignisse erstellen und versenden, die dann die entsprechenden registrierten Ereignishandler auslösen, aber sie wird keinen Text erzeugen wenn sie z. B. an ein Eingabeelement gesendet werden.
Um die Texteingabe vollständig zu simulieren, müssen Sie eine Folge von Tastaturereignissen erzeugen und den Text des Eingabeelements explizit festlegen. Die Reihenfolge der Ereignisse hängt davon ab, wie genau Sie die Texteingabe simulieren wollen.
Die einfachste Form wäre die folgende:
$('input').val('123');
$('input').change();
In einigen Fällen keypress
Ereignis kann die erforderliche Funktionalität nicht bereitstellen. Von Mozilla-Dokumente können wir sehen, dass die Funktion veraltet ist:
Diese Funktion wird nicht mehr empfohlen. Auch wenn einige Browser sie noch unterstützen, kann es sein, dass sie bereits aus den einschlägigen Webstandards entfernt wurde, dass sie gerade entfernt wird oder dass sie nur noch aus Kompatibilitätsgründen verwendet wird. Vermeiden Sie die Verwendung dieser Funktion und aktualisieren Sie, wenn möglich, den vorhandenen Code; die Kompatibilitätstabelle am Ende dieser Seite hilft Ihnen bei Ihrer Entscheidung. Beachten Sie, dass diese Funktion jederzeit auslaufen kann.
Da also die keypress
Ereignis wird aus den beiden daraufhin ausgelösten Ereignissen kombiniert keydown
und das folgende es keyup
für denselben Schlüssel, erzeugen Sie die Ereignisse einfach nacheinander:
element.dispatchEvent(new KeyboardEvent('keydown',{'key':'Shift'}));
element.dispatchEvent(new KeyboardEvent('keyup',{'key':'Shift'}));
Für diejenigen, die es interessiert, können Sie in der Tat Tastatur-Eingabe-Ereignisse zuverlässig nachbilden. Um Text im Eingabebereich zu ändern (Cursor bewegen oder die Seite über ein Eingabezeichen), müssen Sie das DOM-Ereignismodell genau befolgen: http://www.w3.org/TR/DOM-Level-3-Events/#h4_events-inputevents
Das Modell sollte ausreichen:
- Fokus (wird auf dem DOM mit dem eingestellten Ziel versendet)
Dann für jedes Zeichen:
- Tastendruck (wird im DOM ausgeführt)
- beforeinput (wird am Ziel gesendet, wenn es sich um eine Textarea oder eine Eingabe handelt)
- Tastendruck (wird auf dem DOM ausgeführt)
- input (wird am Ziel gesendet, wenn es sich um eine Textarea oder eine Eingabe handelt)
- ändern (wird am Ziel gesendet, wenn es ein Select ist)
- keyup (wird auf dem DOM ausgeführt)
Dann, optional für die meisten:
- blur (wird auf dem DOM mit dem eingestellten Ziel versendet)
Dies ändert tatsächlich den Text in der Seite über Javascript (ohne Änderung der Wert-Anweisungen) und setzt alle Javascript-Listener/Handler entsprechend aus. Wenn Sie die Sequenz durcheinander javascript wird nicht in der entsprechenden Reihenfolge Feuer, wird der Text im Eingabefeld nicht ändern, die Auswahlen nicht ändern oder der Cursor wird nicht auf das nächste Feld im Textbereich zu bewegen.
Leider wurde der Code für einen Arbeitgeber geschrieben, der einem NDA unterliegt, so dass ich ihn nicht weitergeben kann, aber es ist definitiv möglich, aber Sie müssen den gesamten Tasteneingabe-"Stapel" für jedes Element in der richtigen Reihenfolge neu erstellen.
Aufbauend auf der Antwort von alex2k8, hier eine überarbeitete Version, die in allen Browsern funktioniert, die jQuery unterstützt (das Problem lag in den fehlenden Argumenten für jQuery.event.trigger, die man leicht vergisst, wenn man diese interne Funktion verwendet).
// jQuery plugin. Called on a jQuery object, not directly.
jQuery.fn.simulateKeyPress = function (character) {
// Internally calls jQuery.event.trigger with arguments (Event, data, elem).
// That last argument, 'elem', is very important!
jQuery(this).trigger({ type: 'keypress', which: character.charCodeAt(0) });
};
jQuery(function ($) {
// Bind event handler
$('body').keypress(function (e) {
alert(String.fromCharCode(e.which));
console.log(e);
});
// Simulate the key press
$('body').simulateKeyPress('x');
});
Man könnte dies sogar noch weiter treiben und nicht nur das Ereignis simulieren, sondern das Zeichen tatsächlich einfügen (wenn es sich um ein Eingabeelement handelt), aber es gibt viele browserübergreifende Probleme, wenn man das versucht. Verwenden Sie besser ein aufwendigeres Plugin wie SendKeys .