ChatGPT解决这个技术问题 Extra ChatGPT

Firing a Keyboard Event in Safari, using JavaScript

I'm trying to simulate a keyboard event in Safari using JavaScript.

I have tried this:

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

...and also this:

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

After trying both approaches, however, I have the same problem: after the code has been executed, the keyCode/which properties of the event object are set to 0, not 115.

Does anyone know how to reliably create and dispatch a keyboard event in Safari? (I'd prefer to achieve it in plain JavaScript if possible.)

Are you trying to execute code you have defined or some key-combination the browser understands? If it's your own code, it might be best to setup an event wrapper that you can either call via a "real" keyboard interface or via some other event generator, as you have described here. Refactoring as appropriate.
In this example, I'm trying to simulate the user pressing "s". Ultimately, I'm trying to simulate the user pressing Command-R in an Apple Dashboard Widget.
Your code solved my problem :)
@acidzombie24: My pleasure! :)

t
termi

I am working on DOM Keyboard Event Level 3 polyfill . In latest browsers or with this polyfill you can do something like this:

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

UPDATE:

Now my polyfill supports legacy properties "keyCode", "charCode" and "which"

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

Examples here

Additionally here is cross-browser initKeyboardEvent separately from my polyfill: (gist)

Polyfill demo


Doesn't seem to work for making a scrollable area scroll down using arrow or page up/down keys...
Changed your jsfiddle to dispatch the event on textbox instead of document @ jsfiddle.net/vnathalye/yjc5F/974. Though it fires the keypress handler, the text doesn't get displayed in textbox. Any idea?
@termi Your demo link is dead
Doesn't seem to work for changing the value of an input (text) element either.
The operand of a delete operator cannot be a read-only property.
t
tyronegcarter

Did you dispatch the event correctly?

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

If you use jQuery, you could do:

function simulateKeyPress(character) {
  jQuery.event.trigger({ type : 'keypress', which : character.charCodeAt(0) });
}

Is it possible to simulate control + C (copy shortcut) with this?
@claudiopro Yes, you are correct it should be (evt.initKeyEvent || evt.initKeyboardEvent).call(evt, // etc.
The initKeyboardEvent doesn't work in Chromium either. event.keyCode and event.whichalways return 0. It's a known bug and the workaround is to use a regular event var event = document.createEvent('Event'); event.initEvent('keydown', true, true); event.keyCode = 76;
Downvoted: initKeyEvent and initKeyboardEvent are DEPRECATED.
@K._ instead of downvoting for a previously functioning answer, stating that it's deprecated should be sufficient to give everyone a heads-up without negatively affecting tyronegcarter. This answer stackoverflow.com/questions/961532/… uses the modern KeyboardEvent developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent/…
C
Community

This is due to a bug in Webkit.

You can work around the Webkit bug using createEvent('Event') rather than createEvent('KeyboardEvent'), and then assigning the keyCode property. See this answer and this example.


i
ibrahim mahrir

The Mozilla Developer Network provides the following explanation:

Create an event using event = document.createEvent("KeyboardEvent") Init the keyevent

using:

event.initKeyEvent (type, bubbles, cancelable, viewArg, 
       ctrlKeyArg, altKeyArg, shiftKeyArg, metaKeyArg, 
           keyCodeArg, charCodeArg)

Dispatch the event using yourElement.dispatchEvent(event)

I don't see the last one in your code, maybe that's what you're missing. I hope this works in IE as well...


Unfortunately, Mozilla's implementation is non-standard. As for point 3, my problem is creating the correct event—dispatching the event comes after this. Also, since I'm developing for Apple's Dashboard, I don't have to worry about IE at all! (Whoopee!)
.initKeyEvent is now deprecated
v
vutar

I am not very good with this but KeyboardEvent => see KeyboardEvent is initialized with initKeyEvent .
Here is an example for emitting event on <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);


it shows 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 :(
It should be: var kEvent = document.createEvent("KeyboardEvent"); kEvent.initKeyboardEvent("keypress", true, true, null, false, false, false, false, 74, 74); document.dispatchEvent(kEvent);