I have a very contrived example where I want to programmatically generate a click event on a textbox when a user clicks on a button. I can see that the textbox gets the event but the focus doesn't change to the textbox.
I know I can call focus()
but my goal is to use dispatchEvent
and mouse events only.
This comes from a large app where I have a transparent IFrame over the whole page (imagine a transparent layer with some custom content on top of Google Maps). The IFrame's content can come from a 3rd party which may choose to either handle the click event, or propagate it up to the parent (kind of like bubbling up but across frame boundaries).
While doing so, I noticed that some elements on the parent page (like text boxes and buttons) don't behave as I would normally expect so I produced this small example to illustrate the problem.
function handleClick(event)
{
let textbox = document.getElementById('text');
let rect = textbox.getBoundingClientRect();
let newEvent = new MouseEvent('click', {
clientX: rect.x + 5,
clientY: rect.y + 5,
x: rect.x + 5,
y: rect.y + 5,
pageX: rect.x + 5,
pageY: rect.y + 5
});
textbox.dispatchEvent(newEvent);
}
<input type="text" id="text" onclick="console.log('clicked')" />
<button onclick="handleClick(event)">Click</button>
Call focus()
(MDN) on the element you want to focus.
You can also use click()
(MDN) to simulate a mouse click.
document.querySelector('#button').addEventListener('click', () => {
const inp = document.querySelector('#inp')
inp.focus()
inp.click()
})
<input type="text" id="inp" onclick="console.log('clicked')" />
<button id="button">Click</button>
Here it is using your code example.
function handleClick(event)
{
let textbox = document.getElementById('text');
let rect = textbox.getBoundingClientRect();
let newEvent = new MouseEvent('click', {
clientX: rect.x + 5,
clientY: rect.y + 5,
x: rect.x + 5,
y: rect.y + 5,
pageX: rect.x + 5,
pageY: rect.y + 5
});
textbox.dispatchEvent(newEvent);
}
function clickCallback(event) {
event.target.focus()
event.target.click()
}
<input type="text" id="text" onclick="clickCallback(event)" />
<button onclick="handleClick(event)">Click</button>