¿Es posible simular eventos de prensa clave mediante programación?

Resuelto tan asked hace 15 años • 0 respuestas

¿Es posible simular eventos de pulsación de teclas mediante programación en JavaScript?

tan avatar Feb 28 '09 03:02 tan
Aceptado

Una versión sin jquery que funciona tanto en webkit como en 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);
Philip Nuzhnyy avatar Aug 29 '2012 22:08 Philip Nuzhnyy

Puede enviar eventos de teclado en un EventTarget(elemento, ventana, documento, otros) como este:

element.dispatchEvent(new KeyboardEvent('keydown', {'key': 'a'}));

Sin embargo, dispatchEventes posible que no actualice el valor del campo de entrada y que no desencadene el comportamiento que ocurre al presionar el teclado con regularidad, probablemente debido a la Event.isTrustedpropiedad, que no sé si hay una manera de evitarlo.

Pero también puedes cambiar una entrada configurando su value.

element.value += "a";

Ejemplo:

const element = document.querySelector('input');

element.addEventListener('keydown', e => console.log(e.key));
changeValButton.addEventListener('click', () => { element.value += "a"; });
dispatchButton.addEventListener('click', () => {
    const event = new KeyboardEvent('keydown', {'key': 'a'});

    element.dispatchEvent(event);
});
<input/>
<button id="dispatchButton">Press to dispatch event </button>
<button id="changeValButton">Press to change value </button>
Expandir fragmento


Puede agregar más propiedades al evento según sea necesario, como en esta respuesta . Echa un vistazo a la KeyboardEventdocumentación.

element.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.
}));

Además, como keypressestá en desuso , puedes usar keydown+ keyup, por ejemplo:

element.dispatchEvent(new KeyboardEvent('keydown', {'key':'Shift'} ));
element.dispatchEvent(new KeyboardEvent( 'keyup' , {'key':'Shift'} ));

Para páginas con ReactJS, consulte: ¿ Cómo completar mediante programación elementos de entrada creados con React? sobre cómo simular el comportamiento del teclado.

aljgom avatar May 25 '2017 22:05 aljgom

Si está bien utilizar 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");
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/1.3.1/jquery.min.js">
</script>
Expandir fragmento

alex2k8 avatar Feb 27 '2009 20:02 alex2k8

Lo que puede hacer es activar mediante programación oyentes de eventos clave activando eventos clave . Tiene sentido permitir esto desde una perspectiva de seguridad protegida. Usando esta habilidad, puedes aplicar un patrón de observador típico . Podrías llamar a este método "simular".

A continuación se muestra un ejemplo de cómo lograr esto en el estándar DOM W3C junto con 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 ejemplo está adaptado de: https://developer.mozilla.org/en-US/docs/Web/Guide/Events/Creating_and_triggering_events

En jQuery:

jQuery('input[type=submit][name=btnK]')
  .trigger({
    type: 'keypress',
    which: character.charCodeAt(0 /*the key to trigger*/)      
   });

Pero hasta hace poco, no existe una forma [DOM] de activar eventos clave que salgan del entorno de pruebas del navegador. Y todos los principales proveedores de navegadores se adherirán a ese concepto de seguridad.

En cuanto a complementos como Adobe Flash, que se basan en NPAPI, y permiten eludir el entorno de pruebas: están en desuso ; Firefox .

Explicación detallada:

No puedes ni debes hacerlo por razones de seguridad (como ya señaló Pekka). Siempre necesitarás una interacción del usuario en el medio. Además, imagine la posibilidad de que los usuarios demanden a los proveedores de navegadores, ya que varios eventos de teclado programático habrán dado lugar a ataques de suplantación de identidad.

Consulte esta publicación para conocer alternativas y más detalles. Siempre existe el copiar y pegar basado en flash. He aquí un ejemplo elegante . Al mismo tiempo, es un testimonio de por qué la web se está alejando de los proveedores de complementos.

Se aplica una mentalidad de seguridad similar en el caso de la política CORS de suscripción voluntaria para acceder a contenido remoto mediante programación.

La respuesta es:
en circunstancias normales, no hay forma de activar claves de entrada mediante programación en el entorno de espacio aislado del navegador .

En pocas palabras: no estoy diciendo que no será posible en el futuro, bajo modos especiales de navegador y/o privilegios para el objetivo final de los juegos, o experiencias de usuario similares. Sin embargo, antes de ingresar a dichos modos, se le pedirán permisos y riesgos al usuario, similar al modelo API de pantalla completa .

Divulgación: la respuesta se basa en la respuesta aquí .

Lorenz Lo Sauer avatar Nov 09 '2013 22:11 Lorenz Lo Sauer