1

I've been attempting to programmatically simulate a mouse click at arbitrary coordinates on a canvas element. Because of technology constraints, I need to avoid jQuery which would make this easier.

Using this answer, I am able to get coordinates of manual clicks.

Using this answer, I'm able to programmatically simulate a mouse click. But unfortunately I need to de-jQuery-ify it, which is, I think, where I've run into problems.

If I try to do something like:

document.querySelector("canvas").dispatchEvent(new Event("mousedown", {pageX: 1, pageY: 1}));

or

document.querySelector("canvas").dispatchEvent(new MouseEvent("mousedown", {pageX: 1, pageY: 1}));

or combinations of the above using 'click' instead of 'mousedown'

I still get strange 'undefined' errors that I don't understand (other than that I can see they are referring to 'mousedown') and never successfully simulate the click.

Some working (and not working) examples:

Working: Displays coordinates of clicks

Working: Fires a programmatic click

Not Working: Combining the two above

Not Working: Trying to fire a programmatic click without jQuery

David Bandel
  • 252
  • 3
  • 19

1 Answers1

2

The problem with your jQuery approach is that you are mixing it with a plain JavaScript event listener. This does not work with jQuery.

If you want to trigger an event and listen it using jQuery you have to use it's .trigger() and .mousedown() methods.

Here's an example:

function getMousePosition(canvas, event) {
  let rect = canvas.getBoundingClientRect();
  let x = event.clientX - rect.left;
  let y = event.clientY - rect.top;
  document.getElementById('output').innerText = x + ", " + y;
}

canvasElem = document.querySelector("canvas");

$('#canvas_element').mousedown(function(e) {
  getMousePosition(canvasElem, e);
});

var e = jQuery.Event("mousedown", {
  clientX: 50,
  clientY: 50
});
$('#canvas_element').trigger(e);
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<canvas id="canvas_element"></canvas>
<div id="output"></div>

All of the above can be done using just JavaScript too of course.

function getMousePosition(canvas, event) {
  let rect = canvas.getBoundingClientRect();
  let x = event.clientX - rect.left;
  let y = event.clientY - rect.top;
  document.getElementById('output').innerText = x + ", " + y;
}

canvasElem = document.querySelector("canvas");

canvasElem.addEventListener("mousedown", function(e) {
  getMousePosition(canvasElem, e);
});

canvasElem.dispatchEvent(new MouseEvent("mousedown", {
  clientX: 50,
  clientY: 50
}));
<canvas id="canvas_element"></canvas>
<div id="output"></div>
obscure
  • 11,916
  • 2
  • 17
  • 36
  • Thanks for the help. So my js approach was literally only not working because I was using pageX and not clientX? None of the answers or posts/blogs/articles I'd read anywhere specified anything about that... is there any documentation anywhere that makes this stuff understandable without this level of headache? – David Bandel Jan 31 '22 at 16:39
  • No problem David - glad I could help! The different position properties a mouse event returns are indeed a bit confusing. There's a nifty summary over here: [https://www.codetd.com/en/article/12514516](https://www.codetd.com/en/article/12514516) – obscure Jan 31 '22 at 16:48
  • That's an excellent resource, bookmarked – David Bandel Jan 31 '22 at 18:08