Detect touchpad vs mouse in Javascript

The answer above by Lauri seems to work, but it took me a while to understand why it works. So here I’ll provide a slightly more human readable version, along with a conceptual explanation. First, that same code written out in a human readable manner:

function detectTrackPad(e) {
  var isTrackpad = false;
  if (e.wheelDeltaY) {
    if (e.wheelDeltaY === (e.deltaY * -3)) {
      isTrackpad = true;
    }
  }
  else if (e.deltaMode === 0) {
    isTrackpad = true;
  }
  console.log(isTrackpad ? "Trackpad detected" : "Mousewheel detected");
}

document.addEventListener("mousewheel", detectTrackPad, false);
document.addEventListener("DOMMouseScroll", detectTrackPad, false);

This works because wheelDeltaY measures the physical distance that the actual hardware mouse wheel has travelled, while deltaY measures the amount of scrolling produced on screen. A conventional mouse typically has a much lower “scroll resolution” than a trackpad. That is to say, with a trackpad you can make a tiny motion and a get a tiny scroll on screen. A conventional mouse scrolls in chunkier, low resolution clicks. To complete a full rotation of the mouse wheel, it might make 10 clicks. There is no such thing as a half click or quarter click.

For a conventional mouse, a single wheel click is reported as 120 wheelDeltaY “units” and results in about ~100px worth of scrolling. The physical wheelDeltaY unit is a completely arbitrary number, it is not measuring inches or degrees or anything like that. The number 120 was selected simply because it has a lot of useful factors. The amount of scrolling on screen is represented by deltaY, and it varies significantly by browser. (Sidenote, deltaY is generally measured in “lines” not pixels, though it’s complicated, see previous link).

mouse cutaway

Interacting with a trackpad is different in two ways. First of all, you can get wheelDeltaY values much smaller than 120, because very subtle finger gestures are detectable. Second, the wheelDeltaY is exactly 3x the deltaY value (at least in every browser I’ve managed to test). So, for instance, if you make a physical finger gesture equal to 12 click units, it will generally result in 4 pixels worth of scrolling. Lauri’s code uses this second property (Y1 = Y2 * 3) to detect the existence of a trackpad, but you could probably also be successful simply by checking if abs(wheelDeltaY) equals 120

I haven’t tested this, but I think it would also work:

function detectTrackPad(e) {
  var isTrackpad = false;
  if (e.wheelDeltaY) {
    if (Math.abs(e.wheelDeltaY) !== 120) {
      isTrackpad = true;
    }
  }
  else if (e.deltaMode === 0) {
    isTrackpad = true;
  }
  console.log(isTrackpad ? "Trackpad detected" : "Mousewheel detected");
}

document.addEventListener("mousewheel", detectTrackPad, false);
document.addEventListener("DOMMouseScroll", detectTrackPad, false);

Leave a Comment

tech