Можно ли программным образом моделировать события нажатия клавиш в JavaScript?
Можно ли программным образом моделировать ключевые события пресса?
Ответ 1
Версия не-jquery, которая работает как в webkit, так и в gecko:
var keyboardEvent = document.createEvent("KeyboardEvent");
var initMethod = typeof keyboardEvent.initKeyboardEvent !== 'undefined' ? "initKeyboardEvent" : "initKeyEvent";
keyboardEvent[initMethod](
"keydown", // event type: keydown, keyup, keypress
true, // bubbles
true, // cancelable
window, // view: should be window
false, // ctrlKey
false, // altKey
false, // shiftKey
false, // metaKey
40, // keyCode: unsigned long - the virtual key code, else 0
0 // charCode: unsigned long - the Unicode character associated with the depressed key, else 0
);
document.dispatchEvent(keyboardEvent);
Ответ 2
Если вам удобно использовать jQuery 1.3.1:
function simulateKeyPress(character) {
jQuery.event.trigger({ type : 'keypress', which : character.charCodeAt(0) });
}
$(function() {
$('body').keypress(function(e) {
alert(e.which);
});
simulateKeyPress("e");
});
Ответ 3
То, что вы можете сделать, это программно запускать слушатели ключевых событий путем запуска ключевых событий. Имеет смысл разрешить это с точки зрения безопасности. Используя эту способность, вы можете применить типичный шаблон наблюдателя. Вы можете назвать этот метод "имитацией".
Ниже приведен пример того, как этого добиться в стандарте W3C DOM вместе с jQuery:
function triggerClick() {
var event = new MouseEvent('click', {
'view': window,
'bubbles': true,
'cancelable': true
});
var cb = document.querySelector('input[type=submit][name=btnK]');
var canceled = !cb.dispatchEvent(event);
if (canceled) {
// preventDefault was called and the event cancelled
} else {
// insert your event-logic here...
}
}
Этот пример адаптирован из: https://developer.mozilla.org/en-US/docs/Web/Guide/Events/Creating_and_triggering_events
В jQuery:
jQuery('input[type=submit][name=btnK]')
.trigger({
type: 'keypress',
which: character.charCodeAt(0 /*the key to trigger*/)
});
Но в последнее время [DOM] не существует способа вызвать события, оставляющие браузер-песочницу. И все основные поставщики браузеров будут придерживаться этой концепции безопасности.
Что касается плагинов, таких как Adobe Flash, которые основаны на NPAPI- и позволяют обходить песочницу: это постепенный отказ; Firefox.
Детальное объяснение:
Вы не можете и не должны по соображениям безопасности (как уже указывал Пекка). Вы всегда будете требовать взаимодействия пользователя между ними. Кроме того, представьте, что пользователи браузеров могут подать в суд на пользователей, поскольку различные программные события на клавиатуре приведут к подделке атак.
Смотрите этот пост для альтернатив и более подробной информации. Всегда есть флэш на основе копирования и вставки. Вот элегантный пример. В то же время это свидетельство того, почему Интернет отодвигается от поставщиков плагинов.
В случае политики CORS opt-in применяется аналогичный подход к безопасности для программного доступа к удаленному контенту.
Ответ:
В нормальных условиях нет возможности программно запускать клавиши ввода в изолированной среде браузера.
Итог: я не говорю, что это не будет возможно в будущем, при специальных режимах браузера и/или привилегиях для достижения конечной цели игры или подобного пользовательского опыта. Однако до входа в такие режимы у пользователя будут запрашиваться разрешения и риски, аналогичные модели полноэкранного API.
Полезно: в контексте KeyCodes этот инструмент и сопоставление кодов ключей пригодятся.
Раскрытие: ответ основан на ответе здесь.
Ответ 4
Вы можете отправлять события клавиатуры на элемент вроде этого
element.dispatchEvent(new KeyboardEvent('keypress',{'key':'a'}));
Ответ 5
Вы можете использовать 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");
}
}
Я не тестировал это, но он был адаптирован из кода в документации dispatchEvent(). Вы, вероятно, захотите прочитать это, а также документы для createEvent() и initKeyEvent().
Ответ 6
Вы можете создавать и отправлять события клавиатуры, и они будут запускать соответствующие зарегистрированные обработчики событий, однако они не будут выводить текст, если отправлено, например, в элемент ввода.
Чтобы полностью имитировать ввод текста, вам нужно создать последовательность событий клавиатуры и явно задать текст элемента ввода. Последовательность событий зависит от того, насколько тщательно вы хотите имитировать ввод текста.
Простейшая форма:
$('input').val('123');
$('input').change();
Ответ 7
Основываясь на ответе от alex2k8, здесь пересмотренная версия, которая работает во всех браузерах, поддерживаемых jQuery (проблема заключалась в отсутствии аргументов в jQuery.event.trigger, что легко забыть при использовании этой внутренней функции).
// 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');
});
Вы можете даже нажать это дальше и позволить ему не только имитировать событие, но и фактически вставлять символ (если это элемент ввода), однако при попытке сделать это есть много кросс-браузеров. Лучше использовать более сложный плагин, например SendKeys.
Ответ 8
В некоторых случаях событие keypress
не может обеспечить требуемую функциональность. Из документов Mozilla мы видим, что эта функция устарела:
Эта функция больше не рекомендуется. Хотя некоторые браузеры могут по-прежнему поддерживать его, он, возможно, уже удален из соответствующих веб-стандартов, может быть в процессе удаления или может храниться только в целях совместимости. Избегайте его использования и обновляйте существующий код, если это возможно; см. таблицу совместимости внизу этой страницы, чтобы принять решение. Имейте в виду, что эта функция может перестать работать в любое время.
Таким образом, поскольку событие keypress
объединено из двух последовательно запускаемых событий keydown
и следующих за ним keyup
для одного и того же ключа, просто генерируйте события по одному:
element.dispatchEvent(new KeyboardEvent('keydown',{'key':'Shift'}));
element.dispatchEvent(new KeyboardEvent('keyup',{'key':'Shift'}));
Ответ 9
Для желающих вы можете, на самом деле, повторно воссоздать события ввода с клавиатуры. Чтобы изменить текст во входной области (перемещать курсоры или страницу через входной символ), вы должны внимательно следить за моделью событий DOM: http://www.w3.org/TR/DOM-Level-3-Events/#h4_events-inputevents
Модель должна делать:
- focus (отправлено на DOM с заданным набором)
Затем для каждого символа:
- keydown (отправлено на DOM)
- beforeinput (отправляется в цель, если это текстовая область или вход)
- keypress (отправлено на DOM)
- (отправляется в цель, если ее текстовая область или вход)
- изменить (отправлено в цель, если ее выбрать)
- keyup (отправлено на DOM)
Затем, необязательно для большинства:
- размытие (отправлено на DOM с заданным набором)
Это фактически изменяет текст на странице с помощью javascript (без изменения инструкций значения) и соответствующим образом отсылает слушателей/обработчиков javascript. Если вы испортите последовательность, javascript не будет срабатывать в соответствующем порядке, текст в поле ввода не изменится, выбор не изменится или курсор не переместится в следующее пространство в текстовой области.
К сожалению, код был написан для работодателя под NDA, поэтому я не могу его разделить, но это определенно возможно, но вы должны воссоздать весь ключевой ввод "стек" для каждого элемента в правильном порядке.
Ответ 10
Этот подход поддерживает кросс-браузер, изменяя значение кода ключа. Источник
var $textBox = $("#myTextBox");
var press = jQuery.Event("keypress");
press.altGraphKey = false;
press.altKey = false;
press.bubbles = true;
press.cancelBubble = false;
press.cancelable = true;
press.charCode = 13;
press.clipboardData = undefined;
press.ctrlKey = false;
press.currentTarget = $textBox[0];
press.defaultPrevented = false;
press.detail = 0;
press.eventPhase = 2;
press.keyCode = 13;
press.keyIdentifier = "";
press.keyLocation = 0;
press.layerX = 0;
press.layerY = 0;
press.metaKey = false;
press.pageX = 0;
press.pageY = 0;
press.returnValue = true;
press.shiftKey = false;
press.srcElement = $textBox[0];
press.target = $textBox[0];
press.type = "keypress";
press.view = Window;
press.which = 13;
$textBox.trigger(press);
Ответ 11
просто используйте CustomEvent
Node.prototype.fire=function(type,options){
var event=new CustomEvent(type);
for(var p in options){
event[p]=options[p];
}
this.dispatchEvent(event);
}
4 ex хотите имитировать ctrl + z
window.addEventListener("keyup",function(ev){
if(ev.ctrlKey && ev.keyCode === 90) console.log(ev); // or do smth
})
document.fire("keyup",{ctrlKey:true,keyCode:90,bubbles:true})
Ответ 12
Вот библиотека, которая действительно помогает: https://cdn.rawgit.com/ccampbell/mousetrap/2e5c2a8adbe80a89050aaf4e02c45f02f1cc12d4/tests/libs/key-event.js
Я не знаю, откуда он пришел, но это полезно. Он добавляет метод .simulate()
к window.KeyEvent
, поэтому вы используете его просто с KeyEvent.simulate(0, 13)
для моделирования enter
или KeyEvent.simulate(81, 81)
для 'Q'
.
Я получил его на https://github.com/ccampbell/mousetrap/tree/master/tests.
Ответ 13
Это сработало для меня, и оно имитирует keyup для моей textaera. если вы хотите, чтобы на всей странице просто поместили KeySimulation()
на <body>
как этот <body onmousemove="KeySimulation()">
или если не onmousemove
то onmouseover
работает onmouseover
или onload
.
<script>
function KeySimulation()
{
var e = document.createEvent("KeyboardEvent");
if (e.initKeyboardEvent) { // Chrome, IE
e.initKeyboardEvent("keyup", true, true, document.defaultView, "Enter", 0, "", false, "");
} else { // FireFox
e.initKeyEvent("keyup", true, true, document.defaultView, false, false, false, false, 13, 0);
}
document.getElementById("MyTextArea").dispatchEvent(e);
}
</script>
<input type="button" onclick="KeySimulation();" value=" Key Simulation " />
<textarea id="MyTextArea" rows="15" cols="30"></textarea>
Ответ 14
Вот решение, которое работает в Chrome и Chromium (тестировали только эти платформы). Кажется, у Chrome есть некоторая ошибка или собственный подход к обработке ключевых кодов, поэтому это свойство нужно добавить отдельно к KeyboardEvent.
function simulateKeydown (keycode,isCtrl,isAlt,isShift){
var e = new KeyboardEvent( "keydown", { bubbles:true, cancelable:true, char:String.fromCharCode(keycode), key:String.fromCharCode(keycode), shiftKey:isShift, ctrlKey:isCtrl, altKey:isAlt } );
Object.defineProperty(e, 'keyCode', {get : function() { return this.keyCodeVal; } });
e.keyCodeVal = keycode;
document.dispatchEvent(e);
}
Ответ 15
Единственный ванильный парень веб-инспектора Javascript, готовый для консоли в копировании + вставке (этот парень уже привлекателен для большинства разработчиков, поэтому не пытайтесь его подтекстировать - он должен быть одиноким.. гребным)
var pressthiskey = "q"/* <--- :) !? q for example */;
var e = new Event("keydown");
e.key = pressthiskey;
e.keyCode = e.key.charCodeAt(0);
e.which = e.keyCode;
e.altKey = false;
e.ctrlKey = true;
e.shiftKey = false;
e.metaKey = false;
e.bubbles = true;
document.dispatchEvent(e);
Ответ 16
Вот что мне удалось найти:
function createKeyboardEvent(name, key, altKey, ctrlKey, shiftKey, metaKey, bubbles) {
var e = new Event(name)
e.key = key
e.keyCode = e.key.charCodeAt(0)
e.which = e.keyCode
e.altKey = altKey
e.ctrlKey = ctrlKey
e.shiftKey = shiftKey
e.metaKey = metaKey
e.bubbles = bubbles
return e
}
var name = 'keydown'
var key = 'a'
var event = createKeyboardEvent(name, key, false, false, false, false, true)
document.addEventListener(name, () => {})
document.dispatchEvent(event)
Ответ 17
Я знаю, что вопрос требует javascript способ имитации нажатия клавиш. Но для тех, кто ищет способ сделать jQuery:
var e = jQuery.Event("keypress");
e.which = 13 //or e.keyCode = 13 that simulates an <ENTER>
$("#element_id").trigger(e);
Ответ 18
как только пользователь нажмет клавишу, о которой идет речь, вы можете сохранить ссылку на нее и использовать ее на любом другом HTML-элементе:
EnterKeyPressToEmulate<input class="lineEditInput" id="addr333_1" type="text" style="width:60%;right:0%;float:right" onkeydown="keyPressRecorder(event)"></input>
TypeHereToEmulateKeyPress<input class="lineEditInput" id="addr333_2" type="text" style="width:60%;right:0%;float:right" onkeydown="triggerKeyPressOnNextSiblingFromWithinKeyPress(event)">
Itappears Here Too<input class="lineEditInput" id="addr333_3" type="text" style="width:60%;right:0%;float:right;" onkeydown="keyPressHandler(event)">
<script>
var gZeroEvent;
function keyPressRecorder(e)
{
gZeroEvent = e;
}
function triggerKeyPressOnNextSiblingFromWithinKeyPress(TTT)
{
if(typeof(gZeroEvent) != 'undefined') {
TTT.currentTarget.nextElementSibling.dispatchEvent(gZeroEvent);
keyPressHandler(TTT);
}
}
function keyPressHandler(TTT)
{
if(typeof(gZeroEvent) != 'undefined') {
TTT.currentTarget.value+= gZeroEvent.key;
event.preventDefault();
event.stopPropagation();
}
}
</script>
Ответ 19
Собственный JavaScript с поддержкой TypeScript:
Введите keyCode или любое другое свойство, которое вы используете, и приведите его к KeyboardEventInit.
пример
const event = new KeyboardEvent("keydown", {
keyCode: 38,
} as KeyboardEventInit);
Ответ 20
Важная часть для того, чтобы заставить это работать, - осознать, что charCode
, keyCode
и which
являются всеми устаревшими методами. Поэтому, если код, обрабатывающий событие нажатия клавиши, использует любое из этих трех, он получит поддельный ответ (например, по умолчанию 0).
Пока вы получаете доступ к событию нажатия клавиши не устаревшим методом, таким как key
, вы должны быть в порядке.
Для завершения я добавил основной код Javascript для запуска события:
const rightArrowKey = 39
const event = new KeyboardEvent('keydown',{'key':rightArrowKey})
document.dispatchEvent(event)
Ответ 21
Вы должны использовать некоторую JS-библиотеку с поддержкой для переноса модели событий DOM. Оттуда вы можете запускать и тестировать своих обработчиков.