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

a8jjtwal  于 2023-06-22  发布在  jQuery
关注(0)|答案(7)|浏览(208)

我目前使用以下测试(取自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())
iecba09b

iecba09b1#

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 */
}
2izufjch

2izufjch2#

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

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

说明:鼠标设备(也包括触摸屏笔记本电脑)在触发touchstart之前首先触发mousemove,hasMouse设置为TRUE。触摸设备(也例如触发mousemove的iOS)首先在点击时触发touchstart,然后触发mousemove。这就是为什么hasMouse会被设置为FALSE。
唯一的问题是,这取决于用户交互,该值只有在鼠标移动或touchstart之后才是正确的,因此不能信任在页面加载时使用。

***********************有更好的现代解决方案。我也不建议使用jQuery了。

lyr7nygr

lyr7nygr3#

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

83qze16e

83qze16e4#

@josemmo的回答对我不起作用:在Android手机上连接鼠标matchMedia('(pointer:fine)').matches不匹配.
幸运的是,我成功地完成了另一个媒体查询:hover

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

ruyhziif5#

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/

0qx6xfy6

0qx6xfy66#

没有直接的方法知道,你必须等待触摸事件或鼠标事件。
假设你想检测 * 或者 * 鼠标 * 或者 * 触摸,你可以执行以下操作:监听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)
}
ct3nt3jp

ct3nt3jp7#

截至2021年,pointerevents已在所有主流浏览器中实现。
它给你的可能性,动态检测pointerdevices鼠标,触摸和笔。

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

这当然取决于用户移动鼠标指针。
即使是ipadOS 14.4.2上的Safari也能检测到它,如果AssistiveTouch被激活的话!但是在pointerType检测中似乎有一些怪癖。它在第一次使用鼠标并且没有执行触摸时将pointerType检测为鼠标。但是如果你以后使用触摸,它不会检测和改变为鼠标的pointerType,如果鼠标是在触摸后使用的!不奇怪!

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

在iPad/iPhone上没有用笔测试。谁知道这会显示出哪些怪癖?

相关问题