0

I am trying to dispatch events programatically for keyboard and mouse events.

So far there are few things I have tried. Right now I am able to dispatch mouse events programatically and see the changes:

const element = document.getElementById("element");
const event = new Event('click', {bubbles: true});
element.dispatchEvent(event);

Above method is working fine for Mouse Event. And I have tried following method for keyboard events:

const element = document.getElementById("input-element");
const event = new KeyboardEvent('keypress', {'key': 'e'});
element.dispatchEvent(event);

It seems here that the event is being executed, but the values are not being updated in the input field.

Brian Tompsett - 汤莱恩
  • 5,753
  • 72
  • 57
  • 129
زوہیب خان
  • 390
  • 1
  • 7
  • 21
  • Events are fired for specific actions, when you dispatch an event, the actual action never occurred. That is, you can't force real key clicks with JS. – Teemu Nov 10 '21 at 15:41
  • I am able to to do the actions like 'click' without code. Without actually clicking by myself. But not working or keyboard event. – زوہیب خان Nov 10 '21 at 15:47
  • 1
    What Teemu said. There isn't a way to dispatch an event to trigger the value to update. You just have to update the value directly. If you're trying to do this in an environment for automated testing, usually updating the value then dispatching the event is good enough to simulate the real thing for testing purposes. – samanime Nov 10 '21 at 15:52

1 Answers1

1

There are a number of events that occur when you press a key. None of them result in an input value being changed, but you can use this function to approximate what happens when a key is pressed.

const element = document.getElementById("input-element");
const key = 'e';

var success = triggerKey(key, element);
console.log(success?'success':'fail');

function triggerKey(key, element){
  if(!/^[a-z]$/.test(key)) return false;
  if(!['INPUT','TEXTAREA'].includes(element.tagName)) return false;
  const events = ['keydown', 'keypress', 'textInput', 'keyup'];
  events.forEach(event_name=>{
    const opts = 'textInput' === event_name ? {
      inputType: 'insertText',
      data: key
    } : {
      key: key,
      code: `Key${key.toUpperCase()}`
    };
    const event = 'textInput' === event_name ? 
      new InputEvent('input', opts) :
      new KeyboardEvent(event_name, opts);
    element.dispatchEvent(event);
    if('textInput' === event_name) element.value += key;
  });
  return true;
}
<input id="input-element">
I wrestled a bear once.
  • 22,983
  • 19
  • 69
  • 116
  • This solves the problem up to some extent but not completely. What would be the solution with we want to add something at the middle somewhere? Right now it is only appending the keys. Also, would be good to put async await to dispatch events. – زوہیب خان Nov 11 '21 at 16:35