Я хочу симулировать события keydown для данного элемента textarea на странице html. Поскольку я использую chrome, я вызывал initKeyboardEvent
в моей переменной, и я передал keyCode, который я хочу ввести в текстовое поле. Вот что я пробовал:
var keyEvent = document.createEvent('KeyboardEvent');
keyEvent.initKeyboardEvent('keydown', true, false, null, 0, false, 0, false, 77, 0);
inputNode.dispatchEvent(keyEvent);
В этом коде я печатаю букву m
, однако текстовое поле получает только keyCode 13
, который является ключом Enter
. Итак, я попробовал переопределить код, который я видел в Интернете, который устанавливает значение keyCodeVal, но без успеха
var keyEvent = document.createEvent('KeyboardEvent');
Object.defineProperty(keyEvent, 'keyCode', {
get : function() {
return this.keyCodeVal;
}
});
keyEvent.initKeyboardEvent('keydown', true, false, null, 0, false, 0, false, 77, 0);
keyEvent.keyCodeVal = 77;
inputNode.dispatchEvent(keyEvent);
Есть ли у кого-нибудь идея, как установить значение keyCode?
Ответ 1
Так очень очень близко...
Вам просто нужно переопределить свойство "which". Вот пример кода:
Podium = {};
Podium.keydown = function(k) {
var oEvent = document.createEvent('KeyboardEvent');
// Chromium Hack
Object.defineProperty(oEvent, 'keyCode', {
get : function() {
return this.keyCodeVal;
}
});
Object.defineProperty(oEvent, 'which', {
get : function() {
return this.keyCodeVal;
}
});
if (oEvent.initKeyboardEvent) {
oEvent.initKeyboardEvent("keydown", true, true, document.defaultView, false, false, false, false, k, k);
} else {
oEvent.initKeyEvent("keydown", true, true, document.defaultView, false, false, false, false, k, 0);
}
oEvent.keyCodeVal = k;
if (oEvent.keyCode !== k) {
alert("keyCode mismatch " + oEvent.keyCode + "(" + oEvent.which + ")");
}
document.dispatchEvent(oEvent);
}
Использование образца:
Podium.keydown(65);
Примечание. Этот код не предназначен для работы в IE, Safari или других браузерах. Ну, может быть, с Firefox. YMMV.
Ответ 2
Овервольфильное решение действительно работает.
- Сначала: 'keyCode', 'charCode' и 'which' только для чтения в Safari и IE9 + (по крайней мере).
- Во-вторых: initKeyboardEvent - это беспорядочно. Все браузеры реализуют его по-другому. Даже в webkit существует несколько различных реализаций initKeyboardEvent. И нет "хороших",
путь к initKeyboardEvent в Opera.
- В-третьих: initKeyboardEvent устарел. Вам нужно использовать конструктор initKeyEvent или KeyboardEvent.
Здесь я написал кросс-браузерную функцию initKeyboardEvent (gist):
Пример:
var a = window.crossBrowser_initKeyboardEvent("keypress", {"key": 1, "char": "!", shiftKey: true})
alert(a.type + " | " + a.key + " | " + a.char + " | " + a.shiftKey)
И вот мой DOM Keyboard Event Level 3 polyfill с кросс-браузерным конструктором KeyboardEvent.
Пример:
var a = new KeyboardEvent("keypress", {"key": 1, "char": "!", shiftKey: true})
alert(a.type + " | " + a.key + " | " + a.char + " | " + a.shiftKey)
Пример 2
Пример 3
Важное примечание 1: charCode, keyCode и какие свойства устарели. Поэтому ни мой конструктор crossBrowser_initKeyboardEvent, ни конструктор KeyboardEvent абсолютно не гарантируют правильные значения этих свойств в некоторых браузерах. Вместо этого вы можете использовать свойства "ключ" и "char" или отредактировать gist, чтобы принудительно использовать initEvent в браузерах с charCode для чтения, keyCode и какие свойства.
Важное примечание 2: событие нажатия клавиши устарело и на данный момент не поддерживается в Уровень 3-го уровня клавиатуры polyfill. Это означает, что ключевые и char свойства в событии keypress могут иметь случайные значения. Я работаю над устранением этой проблемы для обратной совместимости.
Ответ 3
Чтобы получить @Orwellophile script для работы с Google Chrome 26.0.1410.65 (в случае с Mac OS X 10.7.5, если это имеет значение), мне пришлось изменить одну строку: его script, похоже, имеет параметры initKeyboardEvent
в другом порядке, чем документация MDN для initKeyboardEvent.
Измененная строка выглядит так:
oEvent.initKeyboardEvent("keydown", true, true, document.defaultView, k, k, "", "", false, "");
Ответ 4
Ну, вышеупомянутые решения действительно работали, также благодаря @dland для подсказки параметра. Вот что я нашел полезным, если вы не можете запустить события в нужном месте.
@Orwellophile script запускает событие в документе. Возможно, прослушиватель событий не всегда зарегистрирован на document
. Я изменил последнюю строку на следующую, и теперь она очень много работает каждый раз.
document.activeElement.dispatchEvent(oEvent);
document.activeElement
всегда запускает событие в элементе, в котором пользователь в данный момент фокусируется.
Ответ 5
Все вышеперечисленные решения работают, но я обнаружил, что один случай они не будут.
Если используется Dart, код Dart, который использует KeyboardEvents, не будет работать в общем событии.
Вы получите что-то вроде get $keyCode undefined.
после того, как я часами стучал головой, я нашел следующий трюк:
function __triggerKeyboardEvent(el, keyCode)
{
var eventObj = document.createEventObject ?
document.createEventObject() : document.createEvent("Events");
var tempKeyboardObj = document.createEvent("KeyboardEvents");
if(eventObj.initEvent){
eventObj.initEvent("keydown", true, true);
}
eventObj.___dart_dispatch_record_ZxYxX_0_ = tempKeyboardObj.___dart_dispatch_record_ZxYxX_0_
eventObj.keyCode = keyCode;
eventObj.which = keyCode;
el.dispatchEvent ? el.dispatchEvent(eventObj) : el.fireEvent("onkeydown", eventObj);
}
Перехватчик Dool-Dart для того, что наше Событие на самом деле является KeyboardEvent, сделал трюк.
Оставив его здесь, для бедного парня, который пытается протестировать приложение Дарт в браузере на основе webkit.