Ответы:
Версия без 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);
keyCode
всегда 0, и я не могу его изменить.
event.which
всегда будет 0
при использовании document.createEvent("KeyboardEvent")
. @lluft поделился подробностями и обходным путем, который работал для меня, в этом комментарии в другой ветке. По сути, вам нужно использовать document.createEvent('Event')
для создания общего события, а затем установить тип keydown
и дать keyCode
свойство, равное charcode ключа.
Если вы можете использовать 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");
});
trigger
нельзя использовать для имитации событий собственного браузера .
То, что вы можете сделать, это программно запускать слушатели ключевых событий путем запуска ключевых событий . Имеет смысл разрешить это с точки зрения безопасности. Используя эту способность, вы можете применить типичный шаблон наблюдателя . Вы можете назвать этот метод "имитацией".
Ниже приведен пример того, как этого добиться в стандарте 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 этот инструмент и сопоставление кодов ключей пригодятся.
Раскрытие: ответ основан на ответе здесь .
Вы можете отправлять события клавиатуры на элемент, подобный этому
element.dispatchEvent(new KeyboardEvent('keypress',{'key':'a'}));
keypress
это устарело, keydown
вместо этого используйте -> developer.mozilla.org/en-US/docs/Web/Events/keypress
Вы можете использовать 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 ().
initKeyEvent
или нет initKeyboardEvent()
. Оба устарели в пользу использования конструктора KeyboardEvent () .
Вы можете создавать и отправлять события клавиатуры, и они будут запускать соответствующие зарегистрированные обработчики событий, однако они не будут генерировать никакого текста , если отправлены, например, в элемент ввода.
Чтобы полностью имитировать ввод текста, необходимо создать последовательность событий клавиатуры и явно указать текст элемента ввода. Последовательность событий зависит от того, насколько тщательно вы хотите смоделировать ввод текста.
Простейшая форма будет:
$('input').val('123');
$('input').change();
В некоторых случаях keypress
событие не может обеспечить требуемую функциональность. Из документации Mozilla мы видим, что эта функция устарела:
Эта функция больше не рекомендуется. Хотя некоторые браузеры могут по-прежнему поддерживать его, он, возможно, уже удален из соответствующих веб-стандартов, может быть в процессе удаления или может храниться только в целях совместимости. Избегайте его использования и обновляйте существующий код, если это возможно; см. таблицу совместимости внизу этой страницы, чтобы принять решение. Имейте в виду, что эта функция может перестать работать в любое время.
Таким образом, поскольку keypress
событие комбинируется из двух последовательно запускаемых событий keydown
и следующих keyup
за ним для одного и того же ключа, просто генерируйте события по одному:
element.dispatchEvent(new KeyboardEvent('keydown',{'key':'Shift'}));
element.dispatchEvent(new KeyboardEvent('keyup',{'key':'Shift'}));
Основываясь на ответе 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 .
Начиная с 2019 года это решение работает для меня:
document.dispatchEvent(
new KeyboardEvent("keydown", {
key: "e",
keyCode: 69, // example values.
code: "KeyE", // put everything you need in this object.
which: 69,
shiftKey: false, // you don't need to include values
ctrlKey: false, // if you aren't going to use them.
metaKey: false // these are here for example's sake.
})
);
Я использовал это в своей браузерной игре, чтобы поддерживать мобильные устройства с симулированной клавиатурой.
Пояснение: этот код отправляет одно keydown
событие, в то время как нажатие реальной клавиши вызывает одно keydown
событие (или несколько из них, если оно удерживается дольше), а затем одно keyup
событие, когда вы отпускаете эту клавишу. Если вам нужны keyup
события тоже, также можно моделировать keyup
события путем изменения "keydown"
к "keyup"
в фрагменте кода.
Это также посылает событие для всей веб - страницы, поэтому document
. Если вы хотите, чтобы только определенный элемент получил событие, вы можете заменить его document
на нужный элемент.
Trusted
?)
Для тех, кто заинтересован, вы можете надежно воссоздать события ввода с клавиатуры. Чтобы изменить текст в области ввода (перемещать курсоры или страницу с помощью вводимого символа), необходимо внимательно следовать модели событий DOM: http://www.w3.org/TR/DOM-Level-3-Events/ # h4_events-inputevents
Модель должна делать:
Тогда для каждого персонажа:
Тогда, по выбору, для большинства:
Это на самом деле изменяет текст на странице с помощью javascript (без изменения операторов значений) и соответственно отключает любые прослушиватели / обработчики javascript. Если вы ошибетесь в последовательности, javascript не будет запущен в соответствующем порядке, текст в поле ввода не изменится, выбор не изменится или курсор не переместится на следующий пробел в текстовой области.
К сожалению, код был написан для работодателя под NDA, поэтому я не могу поделиться им, но это определенно возможно, но вы должны воссоздать весь «стек» ввода ключа для каждого элемента в правильном порядке.
Этот подход поддерживает кросс-браузерное изменение значения кода ключа . Источник
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);
просто используйте 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 бывших хотят симулировать 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})
Вот библиотека, которая действительно помогает: 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 .
Это сработало для меня, и это имитирует keyup для моей textaera. если вы хотите его для всей страницы просто поставить KeySimulation()
на <body>
подобных <body onmousemove="KeySimulation()">
или , если не onmousemove
то 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>
initKeyboardEvent
это устарело. ( Источник )
Он был однорядным из-за простоты использования в контексте консоли. Но, вероятно, полезно еще.
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);
Вот решение, которое работает в 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);
}
Вот что мне удалось найти:
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)
Собственный JavaScript с поддержкой TypeScript:
Введите keyCode или любое другое свойство, которое вы используете, и приведите его к KeyboardEventInit.
пример
const event = new KeyboardEvent("keydown", {
keyCode: 38,
} as KeyboardEventInit);
Вот что я попробовал с js / typcript в chrome. Спасибо за этот ответ для вдохновения.
const x = document.querySelector('input');
const keyboardEvent = new KeyboardEvent("keypress", { bubbles: true });
Object.defineProperty(keyboardEvent, "charCode", {
get() {
return 13;
},
});
x.dispatchEvent(keyboardEvent);
как только пользователь нажмет соответствующую клавишу, вы можете сохранить ссылку на нее и использовать ее в любом другом 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>
Вы можете установить keyCode, если вы создаете свое собственное событие, вы можете скопировать существующие параметры из любого реального события клавиатуры (игнорируя цели, так как это задание dispatchEvent) и:
ta = new KeyboardEvent('keypress',{ctrlKey:true,key:'Escape'})
Я знаю, что вопрос требует javascript способ имитации нажатия клавиш. Но для тех, кто ищет способ сделать jQuery:
var e = jQuery.Event("keypress");
e.which = 13 //or e.keyCode = 13 that simulates an <ENTER>
$("#element_id").trigger(e);
Важнейшая часть для того, чтобы заставить это работать, - осознать это charCode
, keyCode
и все ониwhich
являются устаревшими методами . Поэтому, если обработка кода событие нажатия клавиши, использует любое из этих трех, он получит поддельный ответ (например, по умолчанию 0).
Пока вы получаете доступ к событию нажатия клавиши не устаревшим методом, таким как key
, вы должны быть в порядке.
Для завершения я добавил базовый код Javascript для запуска события:
const rightArrowKey = 39
const event = new KeyboardEvent('keydown',{'key':rightArrowKey})
document.dispatchEvent(event)
Я хотел смоделировать нажатие «Tab» ... Разбираясь с ответом Тревора, мы видим, что специальная клавиша, такая как «Tab», действительно нажимается, но мы не видим фактический результат, который имел бы нажатие «Tab» .. ,
попытался с диспетчеризацией этих событий для 'activeElement', а также для объекта глобального документа; оба кода добавлены ниже;
фрагмент ниже:
var element = document.getElementById("firstInput");
document.addEventListener("keydown", function(event) {
console.log('we got key:', event.key, ' keyCode:', event.keyCode, ' charCode:', event.charCode);
/* enter is pressed */
if (event.keyCode == 13) {
console.log('enter pressed:', event);
setTimeout(function() {
/* event.keyCode = 13; event.target.value += 'b'; */
theKey = 'Tab';
var e = new window.KeyboardEvent('focus', {
bubbles: true,
key: theKey,
keyCode: 9,
charCode: 0,
});
document.activeElement.dispatchEvent(e);
e = new window.KeyboardEvent('keydown', {
bubbles: true,
key: theKey,
keyCode: 9,
charCode: 0,
});
document.activeElement.dispatchEvent(e);
e = new window.KeyboardEvent('beforeinput', {
bubbles: true,
key: theKey,
keyCode: 9,
charCode: 0,
});
document.activeElement.dispatchEvent(e);
e = new window.KeyboardEvent('keypress', {
bubbles: true,
key: theKey,
keyCode: 9,
charCode: 0,
});
document.activeElement.dispatchEvent(e);
e = new window.KeyboardEvent('input', {
bubbles: true,
key: theKey,
keyCode: 9,
charCode: 0,
});
document.activeElement.dispatchEvent(e);
e = new window.KeyboardEvent('change', {
bubbles: true,
key: theKey,
keyCode: 9,
charCode: 0,
});
document.activeElement.dispatchEvent(e);
e = new window.KeyboardEvent('keyup', {
bubbles: true,
key: theKey,
keyCode: 9,
charCode: 0,
});
document.activeElement.dispatchEvent(e);
}, 4);
setTimeout(function() {
theKey = 'Tab';
var e = new window.KeyboardEvent('focus', {
bubbles: true,
key: theKey,
keyCode: 9,
charCode: 0,
});
document.dispatchEvent(e);
e = new window.KeyboardEvent('keydown', {
bubbles: true,
key: theKey,
keyCode: 9,
charCode: 0,
});
document.dispatchEvent(e);
e = new window.KeyboardEvent('beforeinput', {
bubbles: true,
key: theKey,
keyCode: 9,
charCode: 0,
});
document.dispatchEvent(e);
e = new window.KeyboardEvent('keypress', {
bubbles: true,
key: theKey,
keyCode: 9,
charCode: 0,
});
document.dispatchEvent(e);
e = new window.KeyboardEvent('input', {
bubbles: true,
key: theKey,
keyCode: 9,
charCode: 0,
});
document.dispatchEvent(e);
e = new window.KeyboardEvent('change', {
bubbles: true,
key: theKey,
keyCode: 9,
charCode: 0,
});
document.dispatchEvent(e);
e = new window.KeyboardEvent('keyup', {
bubbles: true,
key: theKey,
keyCode: 9,
charCode: 0,
});
document.dispatchEvent(e);
}, 100);
} else if (event.keyCode != 0) {
console.log('we got a non-enter press...: :', event.key, ' keyCode:', event.keyCode, ' charCode:', event.charCode);
}
});
<h2>convert each enter to a tab in JavaScript... check console for output</h2>
<h3>we dispatchEvents on the activeElement... and the global element as well</h3>
<input type='text' id='firstInput' />
<input type='text' id='secondInput' />
<button type="button" onclick="document.getElementById('demo').innerHTML = Date()">
Click me to display Date and Time.</button>
<p id="demo"></p>