2

With the event api, it is possible to create a synthetic MouseEvent and have it dispatched programmatically by a DOM element.

By adding an event listener to the document, the event dispatched by the child element can be captured during the bubble phase.

ie:

const element = document.createElement('div')
element.style.background = '#ff0000'
element.style.width = '200px'
element.style.height = '200px'
document.body.appendChild(element)

document.addEventListener('click', event => {
  console.log('Clicked on child element')
  console.log(event)
})

const clickEvent = new MouseEvent('click', {
  bubbles: true,
  cancellable: true,
  clientX: 32,
  clientY: 32,
})

element.dispatchEvent(clickEvent)

MouseEvent Coordinate

Is it possible to programmatically dispatch a MouseEvent or PointerEvent from a parent element and have the event go through capture phase and trigger the event listener of the child element under the coordinate of the mouse event?

Gentle Moose
  • 161
  • 5
  • You already know how to create and dispatch an artificial event. Re-dispatch the event to the child element. Keep in mind that, if the child didn't capture it originally, it probably won't capture it a second time. – Ouroborus Nov 30 '20 at 00:58
  • @Ouroborus The problem is that when the event is dispatched by the document or any parent element it does not trigger the event listener on the child elements so it's not quite the same as if the user had clicked at the determined location. I guess it would be possible to walk the DOM tree and perform a hit test manually but I thought there would be a way to have the browser do it as if a user had clicked. – Gentle Moose Dec 01 '20 at 01:51

1 Answers1

3

It seems that my original question was not properly fomulated. My mistake was to assume that the way to propagate an event down the DOM tree was to have the document dispatch it. My question should have been formulated as so: "How to simulate a click by using x,y coordinates in JavaScript?". I found the answer here.

There is a handy elementFromPoint method on the document that returns element under the specified location so no need to walk the DOM tree and manually perform hit test on elements.

Here what needs to be done:

const simulateClick = (x, y) => {
  const event = new MouseEvent('click', {
    view: window,
    bubbles: true,
    cancelable: true,
    screenX: x,
    screenY: y
  })

  const element = document.elementFromPoint(x, y)
  element.dispatchEvent(event)
}

simulateClick(32, 32)
Gentle Moose
  • 161
  • 5