Auslösen eines Tastaturereignisses in Safari mithilfe von JavaScript

79

Ich versuche, ein Tastaturereignis in Safari mit JavaScript zu simulieren.

Ich habe das versucht:

var event = document.createEvent("KeyboardEvent");
event.initKeyboardEvent("keypress", true, true, null, false, false, false, false, 115, 0);

... und auch das:

var event = document.createEvent("UIEvents");
event.initUIEvent("keypress", true, true, window, 1);
event.keyCode = 115;

Nachdem ich beide Ansätze ausprobiert habe, habe ich jedoch das gleiche Problem: Nachdem der Code ausgeführt wurde, werden die keyCode/ which-Eigenschaften des Ereignisobjekts auf 0nicht gesetzt 115.

Weiß jemand, wie man ein Tastaturereignis in Safari zuverlässig erstellt und versendet? (Ich würde es vorziehen, wenn möglich in einfachem JavaScript zu erreichen.)

Steve Harrison
quelle
Versuchen Sie, von Ihnen definierten Code oder eine vom Browser verstandene Tastenkombination auszuführen? Wenn es sich um Ihren eigenen Code handelt, ist es möglicherweise am besten, einen Ereignis-Wrapper einzurichten, den Sie entweder über eine "echte" Tastaturschnittstelle oder über einen anderen Ereignisgenerator aufrufen können, wie Sie hier beschrieben haben. Refactoring nach Bedarf.
Nolte
1
In diesem Beispiel versuche ich, den Benutzer zu simulieren, der "s" drückt. Letztendlich versuche ich, den Benutzer zu simulieren, der Command-R in einem Apple Dashboard Widget drückt.
Steve Harrison
2
Ihr Code hat mein Problem gelöst :)
@ acidzombie24: Es war mir ein Vergnügen! :)
Steve Harrison
4
Duplikat von simulierten JavaScript-Schlüsselereignissen
Dan Dascalescu

Antworten:

43

Ich arbeite an der Polyfüllung DOM Keyboard Event Level 3 . In den neuesten Browsern oder mit dieser Polyfüllung können Sie Folgendes tun:

element.addEventListener("keydown", function(e){ console.log(e.key, e.char, e.keyCode) })

var e = new KeyboardEvent("keydown", {bubbles : true, cancelable : true, key : "Q", char : "Q", shiftKey : true});
element.dispatchEvent(e);

//If you need legacy property "keyCode"
// Note: In some browsers you can't overwrite "keyCode" property. (At least in Safari)
delete e.keyCode;
Object.defineProperty(e, "keyCode", {"value" : 666})

AKTUALISIEREN:

Jetzt unterstützt meine Polyfüllung die alten Eigenschaften "keyCode", "charCode" und "which".

var e = new KeyboardEvent("keydown", {
    bubbles : true,
    cancelable : true,
    char : "Q",
    key : "q",
    shiftKey : true,
    keyCode : 81
});

Beispiele hier

Zusätzlich ist hier browserübergreifendes initKeyboardEvent getrennt von meiner Polyfüllung: (gist)

Polyfill- Demo

termi
quelle
Scheint nicht zu funktionieren, um einen scrollbaren Bereich mit Pfeil- oder Bild-auf / ab-Tasten nach unten zu scrollen ...
Michael
Ihre jsfiddle wurde so geändert, dass das Ereignis im Textfeld anstelle von document @ jsfiddle.net/vnathalye/yjc5F/974 ausgelöst wird . Obwohl der Tastendruck-Handler ausgelöst wird, wird der Text nicht im Textfeld angezeigt. Irgendeine Idee?
Vivek Athalye
1
@termi Ihr Demo-Link ist tot
Sebastian
Scheint auch nicht zum Ändern des Werts eines Eingabeelements (Textelements) zu funktionieren.
Michael
Der Operand eines Löschoperators kann keine schreibgeschützte Eigenschaft sein.
Flugzeuge
30

Haben Sie die Veranstaltung korrekt versandt?

function simulateKeyEvent(character) {
  var evt = document.createEvent("KeyboardEvent");
  (evt.initKeyEvent || evt.initKeyboardEvent)("keypress", true, true, window,
                    0, 0, 0, 0,
                    0, character.charCodeAt(0)) 
  var canceled = !body.dispatchEvent(evt);
  if(canceled) {
    // A handler called preventDefault
    alert("canceled");
  } else {
    // None of the handlers called preventDefault
    alert("not canceled");
  }
}

Wenn Sie jQuery verwenden, können Sie Folgendes tun:

function simulateKeyPress(character) {
  jQuery.event.trigger({ type : 'keypress', which : character.charCodeAt(0) });
}
Tyronegcarter
quelle
3
Ist es möglich, damit Control + C (Kopierverknüpfung) zu simulieren?
John John Pichler
1
@claudiopro Ja, Sie sind richtig, es sollte sein(evt.initKeyEvent || evt.initKeyboardEvent).call(evt, // etc.
tyronegcarter
12
Das initKeyboardEvent funktioniert auch in Chromium nicht. event.keyCodeund event.whichimmer 0 zurückgeben. Es ist ein bekannter Fehler und die Problemumgehung besteht darin, ein reguläres Ereignis zu verwendenvar event = document.createEvent('Event'); event.initEvent('keydown', true, true); event.keyCode = 76;
lluft
5
Downvoted : initKeyEventund initKeyboardEventsind DEPRECATED .
7онстантин Ван
2
@ K._ anstatt für eine zuvor funktionierende Antwort zu stimmen, sollte die Aussage, dass sie veraltet ist, ausreichen, um allen ein Heads-up zu geben, ohne das Tyronegcarter negativ zu beeinflussen. Diese Antwort stackoverflow.com/questions/961532/... nutzt die moderne Keyboard developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent/...
Bit-less
17

Dies liegt an einem Fehler im Webkit.

Sie können den Webkit-Fehler umgehen, indem Sie createEvent('Event')statt createEvent('KeyboardEvent')und dann die keyCodeEigenschaft zuweisen . Siehe diese Antwort und dieses Beispiel .

John
quelle
8

Das Mozilla Developer Network bietet die folgende Erklärung:

  1. Erstellen Sie ein Ereignis mit event = document.createEvent("KeyboardEvent")
  2. Initiieren Sie das Schlüsselereignis

mit:

event.initKeyEvent (type, bubbles, cancelable, viewArg, 
       ctrlKeyArg, altKeyArg, shiftKeyArg, metaKeyArg, 
           keyCodeArg, charCodeArg)
  1. Versenden Sie das Ereignis mityourElement.dispatchEvent(event)

Ich sehe den letzten in Ihrem Code nicht, vielleicht fehlt Ihnen das. Ich hoffe das funktioniert auch im IE ...

Javache
quelle
2
Leider ist die Implementierung von Mozilla nicht Standard. Was Punkt 3 betrifft, besteht mein Problem darin, das richtige Ereignis zu erstellen - der Versand des Ereignisses erfolgt danach. Da ich für Apples Dashboard entwickle, muss ich mir überhaupt keine Sorgen um den Internet Explorer machen! (Whoopee!)
Steve Harrison
5
.initKeyEventist jetzt veraltet
Hampus Ahlgren
1

Ich bin nicht sehr gut damit, aber KeyboardEvent=> siehe KeyboardEvent wird mit initialisiert initKeyEvent.
Hier ist ein Beispiel für das Ausgeben eines Ereignisses für ein <input type="text" />Element

document.getElementById("txbox").addEventListener("keypress", function(e) {
  alert("Event " + e.type + " emitted!\nKey / Char Code: " + e.keyCode + " / " + e.charCode);
}, false);

document.getElementById("btn").addEventListener("click", function(e) {
  var doc = document.getElementById("txbox");
  var kEvent = document.createEvent("KeyboardEvent");
  kEvent.initKeyEvent("keypress", true, true, null, false, false, false, false, 74, 74);
  doc.dispatchEvent(kEvent);
}, false);
<input id="txbox" type="text" value="" />
<input id="btn" type="button" value="CLICK TO EMIT KEYPRESS ON TEXTBOX" />

vutar
quelle
7
es zeigt js:21TypeError: kEvent.initKeyEvent is not a function. (In 'kEvent.initKeyEvent("keypress", true, true, null, false, false, false, false, 74, 74)', 'kEvent.initKeyEvent' is undefined)in Safari :(
He Yifei
Es sollte sein: var kEvent = document.createEvent ("KeyboardEvent"); kEvent.initKeyboardEvent ("Tastendruck", wahr, wahr, null, falsch, falsch, falsch, falsch, 74, 74); document.dispatchEvent (kEvent);
3боп atтный