在Javascript中检测触摸板与鼠标

Fra*_*rth 19 javascript mouse trackpad touchpad

有没有办法检测客户端是否使用触摸板而不是使用Javascript鼠标?

或者至少可以合理估计使用触摸板而不是鼠标的用户数量?

Lau*_*uri 17

比较 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);
Run Code Online (Sandbox Code Playgroud)


Dav*_*iña 15

这个主题可能已经解决,但答案是无法检测到它.我需要得到一个解决方案,这非常重要.所以我找到了一个可接受的解决方案:

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
            }
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

并注册活动:

document.addEventListener("mousewheel", mouseHandle, false);
document.addEventListener("DOMMouseScroll", mouseHandle, false);
Run Code Online (Sandbox Code Playgroud)

它可能需要一些优化,可能不完美,但它的工作原理!至少它可以检测到macbook触控板.但由于设计我会说它应该适用于pad引入大量事件调用的任何地方.

下面是它的工作原理:

当用户首次滚动时,它将检测并检查在50ms内触发的事件不超过5个,这对于普通鼠标来说是非常不寻常的,但对于触控板则不是.

然后是else部分,这对于检测并不重要,而是一次调用函数的技巧,就像用户滑动时一样.如果我不够清楚,请来找我,让这个工作变得非常棘手,当然不是理想的解决方法.

编辑:我现在尽可能地优化代码.它第二次检测到mouseroll并立即在触控板上滑动.删除了很多重复和不必要的代码.

编辑2我更改了时间检查的数字和分别从50到100和5到10的事件数量.这应该产生更准确的检测.

  • [这里](http://jsfiddle.net/ucLe3hLa/)是这个代码的小提琴,更容易测试最终结果. (2认同)
  • 谢谢.我现在在我的生产网站上使用此代码,它运行良好.我修改你的小提琴以获得即时结果:https://jsfiddle.net/ucLe3hLa/1/ (2认同)
  • 仅当您在触摸板上快速移动时才有效 - 如果我使用此精密触摸板缓慢滚动,它会说它是鼠标:( (2认同)

Mat*_*off 8

劳里上面的答案似乎有效,但我花了一段时间才明白它为什么有效。所以在这里我将提供一个稍微更易读的版本,以及一个概念性的解释。首先,以人类可读的方式写出相同的代码:

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);
Run Code Online (Sandbox Code Playgroud)

这是有效的,因为wheelDeltaY 测量实际硬件鼠标滚轮移动的物理距离,而deltaY 测量屏幕上产生的滚动量。传统鼠标的“滚动分辨率”通常比触控板低得多。也就是说,使用触控板,您可以进行微小的运动并在屏幕上进行微小的滚动。传统鼠标会以更粗、低分辨率的点击滚动。要完成鼠标滚轮的完整旋转,可能需要点击 10 次。没有半点击或四分之一点击之类的东西。

对于传统鼠标,单轮单击报告为 120 wheelDeltaY“单位”,并导致大约100px 的滚动。物理wheelDeltaY 单位是一个完全任意的数字,它不是测量英寸或度数或类似的东西。选择120这个数字只是因为它有很多有用的因素。屏幕上的滚动量由 deltaY 表示,它因浏览器而异。(旁注,deltaY 通常以“线”而不是像素来衡量,尽管它很复杂,请参阅上一个链接)。

鼠标剖面图

与触控板的交互有两种不同的方式。首先,您可以获得远小于 120 的 wheelDeltaY 值,因为可以检测到非常微妙的手指手势。其次,wheelDeltaY 正好是 deltaY 值的 3 倍(至少在我设法测试的每个浏览器中)。因此,例如,如果您做出一个等于 12 个点击单位的物理手指手势,通常会导致 4 个像素的滚动。Lauri 的代码使用第二个属性 (Y1 = Y2 * 3) 来检测触控板的存在,但您也可以通过检查 abs(wheelDeltaY) 是否等于 120 来成功

我还没有测试过这个,但我认为它也可以工作:

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);
Run Code Online (Sandbox Code Playgroud)


DA.*_*DA. 7

你可以检测JS事件.

触摸设备将触发touchstart除鼠标事件之外的触摸事件.

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

  • 对于最近关注这个问题的人来说,我一直在四处寻找,我认为并非所有浏览器(如果有的话)都是如此。希望看到一个消息来源来证明触控板触发触摸事件。 (6认同)

aps*_*ers 5

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

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


Fei*_*Sun 5

由触摸板触发的滚轮事件将给出更小的事件.deltaY,1或2,但由鼠标滚轮触发将给出例如100,200。