javascript 在Javascript中检测触摸板与鼠标

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/10744645/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-26 10:53:39  来源:igfitidea点击:

Detect touchpad vs mouse in Javascript

javascriptmousetouchpadtrackpad

提问by Fragsworth

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

有什么方法可以检测客户端使用的是触摸板还是带有 Javascript 的鼠标?

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

或者至少要对使用触摸板而不是鼠标的用户数量进行一些合理的估计?

采纳答案by apsillers

In the general case, there is no way to do what you want. ActiveX mightallow 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.

在一般情况下,没有办法做你想做的事。ActiveX可能允许您查看和检查 USB 设备,但在最好的情况下,即使这是可能的,这也将您限制为 IE 用户。除此之外,没有办法知道。

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.

您可能能够辨别触摸板用户移动光标的方式(或频率)与鼠标用户移动光标的方式的模式。以这种方式区分物理输入设备是一个非常困难的前景,而且可能完全不可能,所以我在这里包括它只是为了完整性。

回答by David Fari?a

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.

它可能需要一些优化并且可能不够完美,但它确实有效!至少它可以检测到 macbook 触控板。但是由于设计的原因,我想说它应该可以在垫引入大量事件调用的任何地方工作。

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.

当用户第一次滚动时,它会检测并检查在 50 毫秒内触发的事件不超过 5 个,这对于普通鼠标来说是非常不寻常的,但对于触控板来说则不然。

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.

然后是 else 部分,它不是为了检测的重要性,而是在用户滑动时调用一次函数的技巧。如果我不够清楚,请来找我,让这个工作非常棘手,当然这是一个不太理想的解决方法。

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 2I 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.

编辑 2我将时间检查的数量和调用的事件数量分别从 50 更改为 100,将 5 更改为 10。这应该产生更准确的检测。

回答by Lauri

Compare e.wheelDeltaY and e.deltaY (or e.deltaMode in Firefox) to detect touchpad mouse device

比较 e.wheelDeltaY 和 e.deltaY(或 Firefox 中的 e.deltaMode)来检测触摸板鼠标设备

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);

回答by DA.

You could detect JS events.

您可以检测 JS 事件。

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

触摸设备将触发触摸事件,例如touchstart除了鼠标事件之外。

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

非触摸设备只会触发鼠标事件。

回答by Fei Sun

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

触摸板触发的滚轮事件将产生更小的 event.deltaY,1 或 2,但由鼠标滚轮触发将产生 100,200。

回答by Joel Teply

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.

从测试插入鼠标到具有触摸板的 mac 和带有触摸板的 Windows 机器,我可以总结一下我是如何工作的。

  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.

  1. 检测导航器用户代理是否包含“Mobile”或“Mac OS” 如果其中任何一个为真,则它可能是基于触摸的系统,但要努力消除它。将布尔值 h​​asTouchPad 设置为 true

  2. 如果上述情况属实,则检测“鼠标”事件并运行测试,例如高数字、非整数频率或卡尔曼滤波。

  3. 将这些保留在队列中,如果该队列的总和超过阈值,则禁用 hasTouchpad 变量并断开事件。

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;
    }
}

回答by CloakedSec

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.

您可以检查安装到本地包中的设备驱动程序软件是否正常运行。就像在 Windows Synaptics、elan 硬件中一样,对于 UNIX(Linux),您可以只检查在基本安装过程中安装的包。许多包在不同版本的 Linux 和类似 Linux 的系统(不完全是 linux)中以不同的格式出现,但它们对所有包使用相同的包名。刚刚知道拉它的代码。仍在努力。