Handle Mouse And Touch Input With The Pointer Events API
With more and more people using their mobile phones and tablets for web browsing, we as developers have to make sure that our web interfaces are fully accessible via touch. Setting up click
and hover
event listeners sort of works, but it is clearly a leftover solution from the mouse era.
Thankfully, there is a new API in town that accommodates the needs of mouse, touch, and stylus devices. It’s called Pointer events (not to be mistaken with the CSS property of the same name) and it allows us to add event listeners that are better suited for working with all types on input.
Meet The New Events
The new Pointer Event API is an evolved version of the Mouse Event interface we’ve all been using so far. It extends the functionality of the old API and adds support for multi-touch gestures, precise pen input, and overall smoother touchscreen interaction.
- pointerdown – Pointer becomes active
- pointerup – Pointer stops being active
- pointerover, pointerenter – Pointer enters element boundries
- pointerout, pointerleave – Pointer leaves element boundries
- pointermove – Pointer moves while inside the element’s boundries
- pointercancel – Pointer has stopped generating events, e.g. input device deactivated
- gotpointercapture – Pointer has entered pointer capture state, e.g. dragging a movable element
- lostpointercapture – Pointer capture state has ended
Most of the Pointer Events have direct alternatives among the old mouse events. Once the new API gets full browser support we can directly substitute with the more modern alternatives:
const button = document.querySelector("button"); // Instead of mouseover button.addEventListener('mouseover', doSomething); // We can use pointerover button.addEventListener('pointerover', doSomething);
Interacting with a mouse should be the same in both cases. Using fingers or a stylus, however, will be easier to program with the new API.
Recognizing Input Type
An awesome feature of the Pointer Events API is that it can tell which type of input has been used. This can be helpful when you want to ignore some of the input methods or provide special feedback for each one.
button.addEventListener('pointereover', function(ev){ switch(ev.pointerType) { case 'mouse': // The used device is a mouse or trackpad. break; case 'touch': // Input via touchscreen. break; case 'pen': // Stylus input. break; default: // Browser can't recognize the used device. break; } });
Other Properties
The Pointer Events interface provides some some other interesting data as well. It includes all the MouseEvent properties plus the following:
- pointerId – Unique ID for the pointer causing the event.
- width and height – Size of the contact area in pixels.
- pressure – Pressure of touch, if available.
- tiltX and tiltY – The angle at which a stylus is touching the screen.
- isPrimary – Determines whether an event has been emitted by the pirmary pointer device.
Browser Support
Pointer Events are fairly new, so browser compatibility isn’t perfect yet. Chrome (desktop and mobile), Edge, IE, and Opera have full support; Firefox and Safari don’t.
To check whether a browser has the Pointer Events API you can use the window object:
if (window.PointerEvent) { // Pointer Events enabled. } else { // Pointer Events not supported }
A popular open-source pollyfill is also available for those who don’t want to wait for full browser adoption.
Conclusion
Although it doesn’t have full browser support yet, the Pointer Events API is eventually going to take over the old mouse events. It provides a lot of cool features that will increase web accessibility and enable developers to create more advanced touch and stylus-based apps.
If you want to learn more about the Power Events API we recommend checking out these resources:
- Pointing the Way Forward – Article on Google Developers
- Pointer Events – Level 2 – W3C Editor’s Draft
- Pointer Events on MDN