JavaScript mouse basics including events and pit falls.

In client side javaScript mouse events are a way to get mouse cursor positions as well as the state of one or more mouse buttons. The javaScript mouse events are a collection of several types of events that can be attached to the window object, or just about an html element with a method the add event listener.

There are three general event type of interest when working something out with mouse events that are onmousedown, onmosemove, and onmouseup. There are other events of interest, but for the most part I only bother with those three events when working out any kind of user interface that will make use of a mouse if present.

1 - JavaScript mouse events basics

So for a basic example of javaScript mouse events I quickly put together this example that will just display the current state of a the mouse position, and the state of the left mouse button.

In this example I just have a simple state object as well as some helper methods for setting the position of the state object, as well as rendering the state of the values to an html element. I am then just attaching event handlers to the window object with the add event listener method by calling the add event listener method off of the window object. Each time I call the add event listener method I pass a string value for the desired event type I want to attach for, and then a function that will fire each time the event happens.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
<html>
<head>
<title>JavaScript mouse basic example</title>
</head>
<body>
<div id="out"><div>
<script>
// basic state and render stuff
var state = {
down: false,
x: null,
y: null
};
var setPos = function (state, e) {
state.x = e.clientX;
state.y = e.clientY;
};
var render = function (state) {
var out = document.getElementById('out');
out.innerText = 'pos: (' + state.x + ',' + state.y + ' ); down: ' + state.down + ';';
};
// attach events to window
window.addEventListener('mousedown', function (e) {
state.down = true;
setPos(state, e);
render(state);
});
window.addEventListener('mousemove', function (e) {
setPos(state, e);
render(state);
});
window.addEventListener('mouseup', function (e) {
state.down = false;
setPos(state, e);
render(state);
});
render(state);
</script>
</body>
</html>

When this example is up and running in the browser I end up with the current values of the state object being displayed. moving the mouse around will result in the position being updated, and clicking the mouse button will change the value of the down boolean value.

2 - Get element relative position

So one thing that might come up right away is that the position that is obtained from the clientX, and clientY properties might not always be what one might expect. The values are always going to be relative to the start of the browser window rather than an element in that window.

To resolve the issue of the position not being relative to a nested element the get bounding client rect method of the target element of the event object can be used to get the position of the element in the window. These values can then be used to get a position that is relative to the element rather than the whole window.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
<html>
<head>
<title>javascript mouse get element relative</title>
</head>
<body>
<canvas id="out" width="320" height="240" style="position:absolute;left:50px;top:50px;"><canvas>
<script>
// Gte El relative
var getElRelative = function (e) {
var el = e.target,
bx = el.getBoundingClientRect();
return {
x: e.clientX - bx.left,
y: e.clientY - bx.top,
bx: bx
};
};
var setPos = function (state, e) {
var pos = getElRelative(e);
state.x = pos.x;
state.y = pos.y;
};
var render = function (ctx, canvas, state) {
var text = 'pos: (' + state.x + ',' + state.y + ' ); down: ' + state.down + ';';
ctx.fillStyle = 'black';
ctx.fillRect(0, 0, canvas.width, canvas.height);
ctx.fillStyle = 'white';
ctx.fillText(text, 32, 32);
};
// state object
var state = {
down: false,
x: null,
y: null
};
// attach events to canvas
var canvas = document.getElementById('out'),
ctx = canvas.getContext('2d');
canvas.addEventListener('mousedown', function (e) {
state.down = true;
setPos(state, e);
render(ctx, canvas, state);
});
canvas.addEventListener('mousemove', function (e) {
setPos(state, e);
render(ctx, canvas, state);
});
canvas.addEventListener('mouseup', function (e) {
state.down = false;
setPos(state, e);
render(ctx, canvas, state);
});
render(ctx, canvas, state);
</script>
</body>
</html>

This time I went with attaching the events to a canvas element that is the nested element of interest. I could leave the events attached to the window object, but that would result in the events continuing to fire even when I do something with the mouse outside of the canvas element.

3 - Conclusion

So hopefully this post has helped you gain some basic insight into how to get going with a mouse when making a user interface with javaScript. However there is much more to learn and be aware of when it comes to using mouse events, as well as other events such as touch events, and keyboard events. This post does not outline a fully comprehensive input controller module or project or sorts after all as the focus here is just on things that have to do with working with the mouse.

When it comes to working out some kind of project that will work as something that will parse input from an array or sources I made a canvas example post that is an input controller of sorts. This canvas example is one of many such canvas examples that I am working on a little now and then that serve as real projects examples of sorts. So for more on mouse events as well as many other related topics you might want to check that post out.