如何检测设备是否支持鼠标?

时间:2014-01-10 20:47:40

标签: javascript jquery

我目前使用以下测试(取自Modernizr)来检测触控支持:

function is_touch_device() {
    var bool;
    if(('ontouchstart' in window) || window.DocumentTouch && document instanceof DocumentTouch) {
        bool = true;
    } else {
        injectElementWithStyles(['@media (',prefixes.join('touch-enabled),('),mod,')','{#modernizr{top:9px;position:absolute}}'].join(''), function(node) {
            bool = node.offsetTop === 9;
        });
    }
    return bool;
}

但是有些设备是触摸和鼠标驱动的,所以我想要一个单独的功能来检测设备是否有鼠标支持。有什么好办法做这个检查?

最终我的目的是能够做到这些:

if(is_touch_device())

if(has_mouse_support())

if(is_touch_device() && has_mouse_support())

7 个答案:

答案 0 :(得分:9)

只有那个a CSS media

您可以通过获取pointer CSS媒体功能的值来检查某些设备是否有鼠标:

if (matchMedia('(pointer:fine)').matches) {
  // Device has a mouse
}

因为它的CSS甚至不需要使用JavaScript:

@media (pointer: fine) {
  /* Rules for devices with mouse here */
}

答案 1 :(得分:7)

我目前正在使用以下(jQuery),但我还没有在特定设备上发现任何漏洞

$(window).bind('mousemove.hasMouse',function(){
    $(window).unbind('.hasMouse');
    agent.hasMouse=true;
}).bind('touchstart.hasMouse',function(){
    $(window).unbind('.hasMouse');
    agent.hasMouse=false;
});

说明:鼠标设备(也是触摸屏笔记本电脑)首先触发鼠标移动,然后才能触发touchstart并将hasMouse设置为TRUE。触摸设备(也就是iOS,它会触发鼠标移动)点击后首先点击触摸开始,然后鼠标移动。那就是为什么hasMouse将设置为FALSE。

唯一的问题是,这取决于用户交互,只有在鼠标移动或touchstart之后,该值才会正确,因此无法信任在页面加载时使用。

答案 2 :(得分:2)

正如问题评论中提到的那样,特别是https://github.com/Modernizr/Modernizr/issues/869,还没有好的答案。

答案 3 :(得分:1)

var clickHandler = (isMouseEventSupported('click') ? 'click' : 'touchstart');

function isMouseEventSupported(eventName) {
    var element = document.createElement('div');
    eventName = 'on' + eventName;
    var isSupported = (eventName in element);
    if (!isSupported) {
       element.setAttribute(eventName, 'return;');
       isSupported = typeof element[eventName] == 'function';
    }
    element = null;
    return isSupported;
}

这是来自我的朋友/同事的代码,他的基础是:http://perfectionkills.com/detecting-event-support-without-browser-sniffing/

答案 4 :(得分:0)

没有直接的了解方法,您必须等待触摸事件或鼠标事件。

假设您要检测 鼠标触摸,您可以执行以下操作:听取touchstartmousemove(后者可以触发)在没有实际鼠标的触摸设备上)。无论哪一个首先发射,99%必然会成为你正在寻找的东西。

这不会考虑实际上同时拥有这两种设备的设备。

document.addEventListener('mousemove', onMouseMove, true)
document.addEventListener('touchstart', onTouchStart, true)
function onTouchStart(){
  removeListeners()
  // touch detected: do stuff
}
function onMouseMove(){
  removeListeners()
  // mouse detected: do stuff
}
function removeListeners(){
  document.removeEventListener('mousemove', onMouseMove, true)
  document.removeEventListener('touchstart', onTouchStart, true)
}

答案 5 :(得分:0)

@josemmo的答案对我不起作用:在附有鼠标matchMedia('(pointer:fine)').matches的Android手机上不匹配。

幸运的是,我已经成功完成了另一个媒体查询:hover

if (matchMedia('(hover:hover)').matches) {
  // Device has a mouse
}

答案 6 :(得分:0)

截至 2021 年,所有主要浏览器都实现了指针事件。

它使您可以动态检测指针设备鼠标、触摸和笔。

var is_touch_device=(('ontouchstart' in window)||
                    (navigator.maxTouchPoints > 0)||
                    (navigator.msMaxTouchPoints > 0));

var has_mouse_support=false;
document.addEventListener("pointermove", function(evt) {
  var pointerType=evt.pointerType;
  /*** Safari quirk  ***/
  if(pointerType==="touch"&&evt.height===117.97119140625
                         &&evt.height===evt.width)pointerType="mouse";
  /*** Safari quirk  ***/
  has_mouse_support=(pointerType==="mouse");
}

这当然取决于用户移动鼠标指针。

如果 AssistiveTouch 被激活,即使是 ipadOS 14.4.2 上的 safari 也会检测到它!但是那里的指针类型检测似乎有一些怪癖。它在第一次使用鼠标并且未执行任何触摸时将指针类型检测为鼠标。但是如果你以后使用touch,它不会检测并更改为鼠标的pointerType,如果在touch之后使用鼠标!不出意外!

编辑:在对 ipadOS safari 进行了一些弄乱之后我发现,在触摸后使用鼠标时,pointerevent 的宽度和高度完全相同,在 ipadOS 14.4.2 中为 117.97119140625 每个使用时间鼠标。这可以用作不可靠的解决方法。谁知道他们什么时候会改变宽度/高度? ipadOS 中指针移动检测的另一个特点是鼠标移动仅在鼠标按下时检测到。

未在 ipad/iphone 上使用笔进行测试。谁知道这会显示哪些怪癖?