Detect touchpad vs mouse in Javascript

不问归期 提交于 2019-11-27 01:34:56

问题


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?


回答1:


In the general case, there is no way to do what you want. ActiveX might allow you to see and examine USB devices, but in the best case, even if that is somehow possible, that limits you to IE users. Beyond that, there is no way to know.

You might be able to discern patterns in how (or how often) a touchpad user moves the cursor versus how a mouse user might move the cursor. Differentiating between physical input devices in this way is an absurdly difficult prospect, and may be wholly impossible, so I include here it for completeness only.




回答2:


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.




回答3:


You could detect JS events.

A touch device will fire touch events such as touchstart in addition to mouse events.

A non-touch device will only fire the mouse events.




回答4:


Wheel event triggered by touchpad will give much smaller event.deltaY,1 or 2,but trigger by mouse wheel will give like 100,200.




回答5:


Another option is to compare e.wheelDeltaY and e.deltaY or e.deltaMode in Firefox

function handler(e) {
    var isTouchPad = e.wheelDeltaY ? e.wheelDeltaY === -3 * e.deltaY : e.deltaMode === 0
    // your code
    document.body.textContent = isTouchPad ? "isTouchPad" : "isMouse"
}
document.addEventListener("mousewheel", handler, false);
document.addEventListener("DOMMouseScroll", handler, false);



回答6:


You could just check for the device driver softwares installed into the local package as functioning. Like in windows synaptics, elan hardware, as for UNIX(Linux) you could just check for the package installed during the basic installed onto. A lot of packages come in different formats in different versions of Linux and Linux like systems(Not linux entirely) but they use the same package name for all. Just got to know the code to pull it. Still working on it.




回答7:


From testing plugging in a mouse to a mac which does have a touchpad and also a windows machine with one, I can summarize how I got this working.

  1. Detect if the navigator user agent contains "Mobile" or "Mac OS" If either of these are true, it is likely a touch based system, but work to eliminate that. Set boolean hasTouchPad to true

  2. If the above is true, detect "mouse" events and run a test like high numbers, or a frequency of non integers or Kalman filtering.

  3. Keep these in a queue and if that queue's sum passes a threshold, disable the hasTouchpad variable and disconnect the event.

let isMouseCounts: Array<number> = []

if (Client.hasTouchpad) {
    document.addEventListener('wheel', detectMouseType);
}

function detectMouseType(e:WheelEvent) {
    if (!Client.hasTouchpad) return

    let isMouse = e.deltaX === 0 && !Number.isInteger(e.deltaY)

    isMouseCounts.push(isMouse ? 1 : 0)
    if (isMouseCounts.length > 5) isMouseCounts.shift()

    let sum = isMouseCounts.reduce(function(a, b) { return a + b; });

    if (sum > 3 && e.type === "wheel") {
        console.log("Touchpad disabled")
        document.removeEventListener('wheel', detectMouseType);
        Client.hasTouchpad = false;
    }
}



回答8:


This should work:

if ("ontouchstart" in window) ...


来源:https://stackoverflow.com/questions/10744645/detect-touchpad-vs-mouse-in-javascript

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!