Respostas:
Uma versão não-jquery que funciona no webkit e no 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
é sempre 0 e não posso alterá-lo.
event.which
com que sempre ocorra 0
ao usar document.createEvent("KeyboardEvent")
. O @lluft compartilhou os detalhes e uma solução alternativa, que funcionou para mim, neste comentário em um tópico diferente. Basicamente, você precisa usar document.createEvent('Event')
para criar um evento genérico e, em seguida, definir o tipo keydown
e fornecer uma keyCode
propriedade igual ao código da chave.
Se você está bem para usar o 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
não pode ser usado para imitar eventos nativos do navegador .
O que você pode fazer é acionar programaticamente os ouvintes do evento de chave acionando eventos de chave . Faz sentido permitir isso de uma perspectiva de segurança em área restrita. Usando essa capacidade, você pode aplicar um padrão típico de observador . Você pode chamar esse método de "simulação".
Abaixo está um exemplo de como fazer isso no padrão W3C DOM junto com o 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...
}
}
Este exemplo é adaptado de: https://developer.mozilla.org/en-US/docs/Web/Guide/Events/Creating_and_triggering_events
No jQuery:
jQuery('input[type=submit][name=btnK]')
.trigger({
type: 'keypress',
which: character.charCodeAt(0 /*the key to trigger*/)
});
Mas, recentemente, não há [DOM] maneira de realmente acionar eventos importantes saindo da caixa de proteção do navegador. E todos os principais fornecedores de navegadores seguirão esse conceito de segurança.
Quanto aos plug-ins como o Adobe Flash - que são baseados no NPAPI -, e permitem ignorar a sandbox: eles são eliminados gradualmente ; Firefox .
Explicação detalhada:
Você não pode e não deve por motivos de segurança (como já destacou Pekka). Você sempre exigirá uma interação do usuário no meio. Além disso, imagine a chance de os fornecedores de navegadores serem processados pelos usuários, pois vários eventos programáticos do teclado levaram a ataques de falsificação.
Veja este post para alternativas e mais detalhes. Há sempre o copiar e colar baseado em flash. Aqui está um exemplo elegante . Ao mesmo tempo, é um testemunho do motivo pelo qual a Web está se afastando dos fornecedores de plug-ins.
Existe uma mentalidade de segurança semelhante aplicada no caso da política do opt-in para acessar conteúdo remoto programaticamente.
A resposta é:
Não há como acionar programaticamente chaves de entrada no ambiente do navegador em área restrita em circunstâncias normais .
Conclusão: não estou dizendo que não será possível no futuro, sob modos especiais de navegador e / ou privilégios em relação ao objetivo final dos jogos ou experiências similares do usuário. No entanto, antes de entrar nesses modos, o usuário será solicitado a fornecer permissões e riscos, semelhantes ao modelo da API de tela cheia .
Útil: No contexto de KeyCodes, essa ferramenta e o mapeamento de código de chave serão úteis.
Divulgação: a resposta é baseada na resposta aqui .
Você pode despachar eventos do teclado em um elemento como este
element.dispatchEvent(new KeyboardEvent('keypress',{'key':'a'}));
keypress
foi depreciado, usando keydown
-> developer.mozilla.org/pt-BR/docs/Web/Events/keypress
Você pode usar 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");
}
}
Não testei isso, mas ele foi adaptado do código na documentação de dispatchEvent () . Você provavelmente vai querer ler isso e também os documentos para createEvent () e initKeyEvent ().
initKeyEvent
ou não initKeyboardEvent()
. Ambos foram descontinuados em favor do uso do construtor KeyboardEvent () .
Você pode criar e despachar eventos do teclado, e eles acionarão os manipuladores de eventos registrados apropriados; no entanto, eles não produzirão nenhum texto , se despachados para o elemento de entrada, por exemplo.
Para simular totalmente a entrada de texto, você precisa produzir uma sequência de eventos do teclado e definir explicitamente o texto do elemento de entrada. A sequência de eventos depende de quão profundamente você deseja simular a entrada de texto.
A forma mais simples seria:
$('input').val('123');
$('input').change();
Em alguns casos, o keypress
evento não pode fornecer a funcionalidade necessária. Nos documentos do mozilla , podemos ver que o recurso foi descontinuado:
Esse recurso não é mais recomendado. Embora alguns navegadores ainda possam suportá-lo, ele pode já ter sido removido dos padrões relevantes da Web, pode estar em processo de queda ou ser mantido apenas para fins de compatibilidade. Evite usá-lo e atualize o código existente, se possível; consulte a tabela de compatibilidade na parte inferior desta página para orientar sua decisão. Esteja ciente de que esse recurso pode deixar de funcionar a qualquer momento.
Portanto, como o keypress
evento é combinado dos dois eventos acionados consequentemente keydown
, e o seguinte keyup
para a mesma chave, apenas gere os eventos um por um:
element.dispatchEvent(new KeyboardEvent('keydown',{'key':'Shift'}));
element.dispatchEvent(new KeyboardEvent('keyup',{'key':'Shift'}));
Com base na resposta do alex2k8, aqui está uma versão revisada que funciona em todos os navegadores suportados pelo jQuery (o problema estava na falta de argumentos para o jQuery.event.trigger, o que é fácil esquecer ao usar essa função interna).
// 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');
});
Você pode ir além e simular não apenas o evento, mas também inserir o caractere (se for um elemento de entrada); no entanto, existem muitas dicas entre navegadores ao tentar fazer isso. Melhor usar um plugin mais elaborado como o SendKeys .
A partir de 2019, esta solução funcionou para mim:
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.
})
);
Usei isso no jogo do meu navegador, para suportar dispositivos móveis com um teclado simulado.
Esclarecimento: Esse código despacha um único keydown
evento, enquanto uma pressão real na tecla acionaria um keydown
evento (ou vários deles, se for mantido por mais tempo) e, em seguida, um keyup
evento quando você soltar essa tecla. Se você também precisar de keyup
eventos, também é possível simular keyup
eventos alterando "keydown"
para "keyup"
no trecho de código.
Isso também envia o evento para toda a página da Web, daí o document
. Se você desejar que apenas um elemento específico receba o evento, poderá substituir document
o elemento desejado.
Trusted
?)
Para os interessados, é possível recriar de fato os eventos de entrada do teclado de maneira confiável. Para alterar o texto na área de entrada (mover cursores ou a página por meio de um caractere de entrada), é necessário seguir o modelo de evento DOM de perto: http://www.w3.org/TR/DOM-Level-3-Events/ # h4_events-inputevents
O modelo deve fazer:
Depois, para cada personagem:
Em seguida, opcionalmente para a maioria:
Na verdade, isso altera o texto na página via javascript (sem modificar as declarações de valor) e aciona os ouvintes / manipuladores de javascript adequadamente. Se você estragar a sequência, o javascript não será acionado na ordem apropriada, o texto na caixa de entrada não será alterado, as seleções não serão alteradas ou o cursor não se moverá para o próximo espaço na área de texto.
Infelizmente, o código foi escrito para um empregador sob um NDA, portanto não posso compartilhá-lo, mas é definitivamente possível, mas você deve recriar toda a "pilha" de entrada de chave para cada elemento na ordem correta.
Essa abordagem suporta cross-browser alterando o valor do código-chave . Fonte
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);
basta usar 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 quer simular 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})
Aqui está uma biblioteca que realmente ajuda: https://cdn.rawgit.com/ccampbell/mousetrap/2e5c2a8adbe80a89050aaf4e02c45f02f1cc12d4/tests/libs/key-event.js
Não sei de onde veio, mas é útil. Ele adiciona um .simulate()
método a window.KeyEvent
, então você o usa simplesmente KeyEvent.simulate(0, 13)
para simular um enter
ou KeyEvent.simulate(81, 81)
para um 'Q'
.
Comprei-o em https://github.com/ccampbell/mousetrap/tree/master/tests .
Isso funcionou para mim e simula um keyup para o meu textaera. Se você quer para toda a página basta colocar o KeySimulation()
sobre <body>
como esta <body onmousemove="KeySimulation()">
, ou se não onmousemove
, em seguida, onmouseover
ou onload
obras também.
<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
está obsoleto. ( Source )
Ele foi remar uma vez devido ao fácil uso em um contexto de console. Mas provavelmente ainda útil.
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);
Aqui está uma solução que funciona no Chrome e no Chromium (apenas testaram essas plataformas). Parece que o Chrome tem algum bug ou uma abordagem própria para lidar com códigos de chave, portanto essa propriedade deve ser adicionada separadamente ao 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);
}
Isto é o que eu consegui encontrar:
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 nativo com solução suportada por TypeScript:
Digite o keyCode ou a propriedade que você está usando e faça a conversão para KeyboardEventInit
Exemplo
const event = new KeyboardEvent("keydown", {
keyCode: 38,
} as KeyboardEventInit);
Foi o que tentei com js / typescript no chrome. Graças a esta resposta para inspiração.
const x = document.querySelector('input');
const keyboardEvent = new KeyboardEvent("keypress", { bubbles: true });
Object.defineProperty(keyboardEvent, "charCode", {
get() {
return 13;
},
});
x.dispatchEvent(keyboardEvent);
assim que o usuário pressionar a tecla em questão, você poderá armazenar uma referência a ela e usá-la em qualquer outro elemento 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>
você pode definir o keyCode se criar seu próprio evento, copiar parâmetros existentes de qualquer evento real do teclado (ignorando destinos, pois é o trabalho de dispatchEvent) e:
ta = new KeyboardEvent('keypress',{ctrlKey:true,key:'Escape'})
Eu sei que a pergunta pede uma maneira javascript de simular um pressionamento de tecla. Mas para aqueles que procuram uma maneira jQuery de fazer as coisas:
var e = jQuery.Event("keypress");
e.which = 13 //or e.keyCode = 13 that simulates an <ENTER>
$("#element_id").trigger(e);
A parte crítica de começar este trabalho é perceber que charCode
, keyCode
e which
são todos métodos obsoletos . Portanto, se o código que processa o evento de pressionamento de tecla usar qualquer um desses três, ele receberá uma resposta falsa (por exemplo, um padrão de 0).
Desde que você acesse o evento de pressionamento de tecla com um método não preterido, como key
, você deve estar OK.
Para concluir, adicionei o código Javascript básico para acionar o evento:
const rightArrowKey = 39
const event = new KeyboardEvent('keydown',{'key':rightArrowKey})
document.dispatchEvent(event)
Eu queria simular uma imprensa 'Tab' ... Expandindo a resposta de Trevor, podemos ver que uma tecla especial como 'tab' é pressionada, mas não vemos o resultado real que uma imprensa 'tab' teria .. .
tentou enviar esses eventos para 'activeElement', bem como o objeto de documento global - código para os dois adicionados abaixo;
snippet abaixo:
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>