Quick hack to deal with touch and mouse events

If you build web pages that are interactive and work on desktops and mobile devices then chances are that you need to work with touch and click events. For mobile devices you’d want to use events like touchstart, touchmove, and touchend and for desktops you’d use mouse events (mousedown, mousemove, and mouseup).

Most of the time the code you execute as a response to these events is the same between these two platforms. So one way to avoid duplicating your code is to take advantage of the JavaScript’s dynamic nature to inject additional data into the event object and chain the click and touch event listeners.

Here is a snippet of code that illustrates my point:

function init() {
    var el = document.getElementById('myDiv');
    el.addEventListener('mousemove', onMouseMove);
    el.addEventListener('touchmove', onTouchMove);
}

function onMouseMove(e) {
    e.touches = [{clientX: e.clientX, clientY: e.clientY}];
    onTouchMove(e);
}

function onTouchMove(e) {
    //do something with e.touches[0].clientX or e.touches[0].clientY

}

The code should be pretty simple to follow:

  • I register listeners for mousemove and touchmove
  • If the code runs on a desktop then the mousemove listeners will be triggered. When this happens I inject the mouse X and Y position in the event object using the data structure used by touch events (touch events have a touches property, which is an array of objects that follow this pattern: {clientX: value, clientY: value}). The touches property is an array because you can expect more than one touch point on some devices. Then I call the onTouchMove function passing along the modified event object
  • The logic I want to execute for that specific action is declared in a single place, the onTouchMove function

I put together a simple page so you can see the code and test it on you computer/devices: demo here.

What method do you use to deal with this?

5 thoughts on “Quick hack to deal with touch and mouse events

  1. I usually use this approach:

    var clickevent = ‘mousedown’;
    if (‘ontouchstart’ in document.documentElement) {
    // touch events are supported
    clickevent = ‘touchstart’;
    }
    var el = document.getElementById(‘myDiv’);
    el.addEventListener(clickevent, onClick);

  2. I use an approach similar to Jack. I look for the “ontouchstart” in the document.documentElement, but then I keep a global boolean with the results. Then I use a ternary operation when I assign events. Something like element.addEventListener( touch ? ‘touchstart’ : ‘mousedown’, doInputDown ). If you are looking for coordinates, you reference the boolean again so you can make sure you’re getting at the right object (or touch points).

    https://gist.github.com/1691217

  3. I like what you’re doing here, Mihai. Jack’s approach is problematic in devices which have both a mouse and a touchscreen (a setup increasingly common on laptops and notebooks). What happens then, is that the touchscreen driver rightfully fires a touchstart event and immediately after would simulate a mousedown event and a click event if you release the finger quickly.

  4. Interesting ideas. I am not sure I understand what prevents from firing the onTouchMove function twice in devices supporting both event types though.
    Any hint ?

  5. Since the touch events are fired first on devices that incorporate both mouse and touch events, you can cancel mouse events in the touch event handler.

Leave a Reply

Your email address will not be published. Required fields are marked *