Detect touchpad vs mouse in Javascript

Fragsworth picture Fragsworth · May 24, 2012 · Viewed 24k times · Source

Is there any way to detect if the client is using a touchpad vs. a mouse with Javascript?

Or at least to get some reasonable estimate of the number of users that use touchpads as opposed to mice?

Answer

David Fariña picture David Fariña · Jul 2, 2015

This topic may be already solved, but the answer was there is no way to detect it. Well I needed to get a solution, it was very important. So I found a acceptable solution for this problem:

var scrolling = false;
var oldTime = 0;
var newTime = 0;
var isTouchPad;
var eventCount = 0;
var eventCountStart;

var mouseHandle = function (evt) {
    var isTouchPadDefined = isTouchPad || typeof isTouchPad !== "undefined";
    console.log(isTouchPadDefined);
    if (!isTouchPadDefined) {
        if (eventCount === 0) {
            eventCountStart = new Date().getTime();
        }

        eventCount++;

        if (new Date().getTime() - eventCountStart > 100) {
                if (eventCount > 10) {
                    isTouchPad = true;
                } else {
                    isTouchPad = false;
                }
            isTouchPadDefined = true;
        }
    }

    if (isTouchPadDefined) {
        // here you can do what you want
        // i just wanted the direction, for swiping, so i have to prevent
        // the multiple event calls to trigger multiple unwanted actions (trackpad)
        if (!evt) evt = event;
        var direction = (evt.detail<0 || evt.wheelDelta>0) ? 1 : -1;

        if (isTouchPad) {
            newTime = new Date().getTime();

            if (!scrolling && newTime-oldTime > 550 ) {
                scrolling = true;
                if (direction < 0) {
                    // swipe down
                } else {
                    // swipe up
                }
                setTimeout(function() {oldTime = new Date().getTime();scrolling = false}, 500);
            }
        } else {
            if (direction < 0) {
                // swipe down
            } else {
                // swipe up
            }
        }
    }
}

And registering the events:

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

It may need some optimization and is maybe less than perfect, but it works! At least it can detect a macbook trackpad. But due to the design i'd say it should work anywhere where the pad introduces a lot of event calls.

Here is how it works:

When the user first scrolls, it will detect and check that in 50ms not more than 5 events got triggered, which is pretty unusual for a normal mouse, but not for a trackpad.

Then there is the else part, which is not for importance for the detection, but rather a trick to call a function once like when a user swipes. Please come at me if I wasn't clear enough, it was very tricky to get this working, and is of course a less than ideal workaround.

Edit: I optimized the code now as much as I can. It detects the mouseroll on the second time and swipe on trackpad instantly. Removed also a lot of repeating and unnecessary code.

Edit 2 I changed the numbers for the time check and numbers of events called from 50 to 100 and 5 to 10 respectively. This should yield in a more accurate detection.