Запуск клавіатурної події в Safari за допомогою JavaScript


79

Я намагаюся імітувати подію клавіатури в Safari за допомогою JavaScript.

Я спробував це:

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

... а також це:

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

Однак, спробувавши обидва підходи, у мене одна і та ж проблема: після виконання коду для keyCode/ whichвластивостей об'єкта події встановлюється значення 0, а не 115.

Хтось знає, як надійно створити та відправити подію клавіатури в Safari? (Я вважаю за краще досягти цього в простому JavaScript, якщо це можливо.)


Ви намагаєтесь виконати визначений вами код або якусь комбінацію клавіш, яку розуміє браузер? Якщо це ваш власний код, можливо, найкраще встановити обгортку події, яку ви можете викликати через "справжній" інтерфейс клавіатури або за допомогою будь-якого іншого генератора подій, як ви описали тут. Рефакторинг відповідно.
Nolte

1
У цьому прикладі я намагаюся імітувати користувача, що натискає "s". Зрештою, я намагаюся імітувати користувача, який натискає Command-R у віджеті Apple Dashboard.
Стів Гаррісон,

2
Ваш код вирішив мою проблему :)

@ acidzombie24: З задоволенням! :)
Стів Гаррісон,

4
Дублікат
моделювання

Відповіді:


43

Я працюю над поліпоповненням клавіатури DOM рівня 3 . У найновіших браузерах або за допомогою цього поліфілу ви можете зробити щось подібне:

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

ОНОВЛЕННЯ:

Тепер мій поліфіл підтримує застарілі властивості "keyCode", "charCode" і "which"

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

Приклади тут

Додатково тут є крос-браузерний initKeyboardEvent окремо від мого поліфілу: (суть)

Демо-версія Polyfill


Здається, це не працює для того, щоб прокручувана область прокручувалася вниз за допомогою клавіш зі стрілками або сторінками вгору / вниз ...
Майкл

Змінив jsfiddle, щоб надіслати подію в текстове поле замість document @ jsfiddle.net/vnathalye/yjc5F/974 . Хоча це спрацьовує обробник натискання клавіш, текст не відображається в текстовому полі. Будь-яка ідея?
Vivek Athalye

1
@termi Ваше демо-посилання мертве
Себастьян,

Здається, це також не працює для зміни значення вхідного (текстового) елемента.
Майкл

Операнд оператора видалення не може бути властивістю лише для читання.
ніркрафт

30

Ви правильно відправили подію?

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

Якщо ви використовуєте jQuery, ви можете зробити:

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

3
Чи можна за допомогою цього імітувати управління + C (ярлик копіювання)?
Джон Джон Піхлер

1
@claudiopro Так, ви праві, так і повинно бути(evt.initKeyEvent || evt.initKeyboardEvent).call(evt, // etc.
tyronegcarter

12
InitKeyboardEvent також не працює в Chromium. event.keyCodeі event.whichзавжди повертають 0. Це відома помилка, і var event = document.createEvent('Event'); event.initEvent('keydown', true, true); event.keyCode = 76;
обхідним шляхом

5
Downvoted : initKeyEventі initKeyboardEventє DEPRECATED .
Константин Ван

2
@ K._, замість того, щоб проголосувати за раніше функціонуючу відповідь, зазначивши, що вона застаріла, має бути достатньою, щоб забезпечити всім заголовок без негативного впливу на тиронекартер. Ця відповідь stackoverflow.com/questions/961532/… використовує сучасний KeyboardEvent developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent/…
трохи менше


8

Мережа розробників Mozilla надає таке пояснення:

  1. Створіть подію за допомогою event = document.createEvent("KeyboardEvent")
  2. Запустіть подію ключа

за допомогою:

event.initKeyEvent (type, bubbles, cancelable, viewArg, 
       ctrlKeyArg, altKeyArg, shiftKeyArg, metaKeyArg, 
           keyCodeArg, charCodeArg)
  1. Відправити подію за допомогоюyourElement.dispatchEvent(event)

Я не бачу останнього у вашому коді, можливо, саме цього вам не вистачає. Сподіваюся, це працює і в IE ...


2
На жаль, реалізація Mozilla нестандартна. Що стосується пункту 3, моя проблема полягає у створенні правильної події - відправлення події настає після цього. Крім того, оскільки я розробляю інформаційну панель Apple, мені взагалі не доведеться турбуватися про IE! (Вупі!)
Стів Гаррісон,

5
.initKeyEventзараз застарілий
Хампус Альгрен

1

Мені це не дуже добре, але KeyboardEvent=> see KeyboardEvent ініціалізовано за допомогою initKeyEvent.
Ось приклад випуску події на <input type="text" />елемент

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" />


7
це показано 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)в сафарі :(
He Yifei 何 一 非

Це має бути: var kEvent = document.createEvent ("KeyboardEvent"); kEvent.initKeyboardEvent ("натискання клавіші", true, true, null, false, false, false, false, 74, 74); document.dispatchEvent (kEvent);
Любопытный
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.