检测浏览器没有鼠标并且触摸

我正在开发一个非常不同的用于触摸的界面(当你点击时你的手指隐藏屏幕)和鼠标(很大程度上依赖于悬浮预览)来开发一个web应用程序(而不是一个包含有趣文本页面的网站)。 我如何检测到我的用户没有鼠标来为他提供正确的界面? 我打算为鼠标和触摸的人留下一个开关(就像一些笔记本一样)。

浏览器中的触摸事件功能实际上并不意味着用户正在使用触摸设备(例如,Modernizr不会剪切它)。 如果设备有鼠标,正确回答问题的代码应该返回false,否则返回true。 对于使用鼠标和触摸的设备,它应该返回false(不仅仅是触摸)

作为一个方面说明,我的触摸界面也可能适用于仅键盘设备,所以更多的是我正在寻找检测到的鼠标缺失。

为了使需要更清楚,下面是我期待实现的API:

// Level 1


// The current answers provide a way to do that.
hasTouch();

// Returns true if a mouse is expected.
// Note: as explained by the OP, this is not !hasTouch()
// I don't think we have this in the answers already, that why I offer a bounty
hasMouse();

// Level 2 (I don't think it's possible, but maybe I'm wrong, so why not asking)

// callback is called when the result of "hasTouch()" changes.
listenHasTouchChanges(callback);

// callback is called when the result of "hasMouse()" changes.
listenHasMouseChanges(callback);

主要的麻烦是你有以下不同类别的设备/用例:

  • 鼠标和键盘(桌面)
  • 仅触摸(手机/平板电脑)
  • 鼠标,键盘和触摸(触摸笔记本电脑)
  • 触摸和键盘(平板电脑上的蓝牙键盘)
  • 仅限鼠标(禁用用户/浏览首选项)
  • 仅限键盘(禁用用户/浏览首选项)
  • 触摸和鼠标(即从Galaxy Note 2笔悬停事件)
  • 更糟的是,人们可以从其中一些类别转换到其他类别(插入鼠标,连接到键盘),或者用户可能会看到普通笔记本电脑上,直到它们伸出手并触摸屏幕。

    假设浏览器中事件构造函数的存在并不是一种向前推进的好方法(并且它有点不一致),那么你是正确的。 另外,除非你正在跟踪一个非常具体的事件,或者只是试图排除上面的几个类,否则使用事件本身并不完全证明。

    例如,假设您发现用户发布了真正的鼠标移动(而不是来自触摸事件的虚假移动,请参阅http://www.html5rocks.com/en/mobile/touchandmouse/)。

    那又怎么样?

    您启用悬停样式? 你添加更多的按钮?

    无论哪种方式,你都在增加玻璃杯的时间,因为你必须等待事件发生。

    但是当你的高贵用户决定要拔掉他的鼠标并全力以赴时,会发生什么......你是否等待他触摸你现在拥挤的界面,然后在他努力查明你现在拥挤的界面后立即改变它?

    以子弹形式,在https://github.com/Modernizr/Modernizr/issues/869#issuecomment-15264101引用stucox

  • 我们想要检测到鼠标的存在
  • 在事件被解雇之前,Ae可能无法检测到
  • 因此,我们正在检测的是在此会话中是否使用了鼠标 - 它不会立即从页面加载
  • 我们可能也无法检测到没有鼠标 - 直到真实才会被定义(我认为这比在将它设置为假前更有意义)
  • 而且我们可能无法检测到鼠标在会话期间是否断开连接 - 这与用户放弃使用鼠标是无法区分的
  • 另外:浏览器知道用户何时插入鼠标/连接到键盘,但不会将其暴露给JavaScript .. dang!

    这应该引导您到以下内容:

    跟踪给定用户的当前能力是复杂的,不可靠的,并且具有可疑的价值

    虽然渐进式增强的想法在这里应用得非常好。 无论用户的环境如何,都可以建立一个顺畅运作的体验。 然后根据浏览器功能/媒体查询进行假设,以添加在假定的上下文中相对的功能。 鼠标的存在只是不同设备上的不同用户体验您的网站的众多方式之一。 在内核中创建具有优点的东西,不要太担心人们点击按钮的方式。


    如何在文档上侦听mousemove事件? 然后,直到听到该事件,您才认为该设备只是触摸或键盘。

    var mouseDetected = false;
    function onMouseMove(e) {
      unlisten('mousemove', onMouseMove, false);
      mouseDetected = true;
      // initializeMouseBehavior();
    }
    listen('mousemove', onMouseMove, false);
    

    (在适当情况下listenunlisten委托给addEventListenerattachEvent 。)

    希望这不会导致太多的可视化结果,如果您需要基于模式的大规模重新布局,它会吸引人...


    @ Wyatt的回答非常好,让我们有很多想法。

    在我的情况下,我选择了听第一次互动,然后才设置一个行为。 因此,即使用户使用鼠标,如果第一次互动是触摸,我会将其视为触摸设备。

    考虑处理事件的给定顺序:

  • touchstart
  • touchmove
  • touchend
  • 鼠标移到
  • 鼠标移动
  • 鼠标按下
  • 鼠标松开
  • 点击
  • 我们可以假设,如果鼠标事件在触摸之前触发,它是一个真正的鼠标事件,而不是一个模拟的鼠标事件。 示例(使用jQuery):

    $(document).ready(function() {
        var $body = $('body');
        var detectMouse = function(e){
            if (e.type === 'mousedown') {
                alert('Mouse interaction!');
            }
            else if (e.type === 'touchstart') {
                alert('Touch interaction!');
            }
            // remove event bindings, so it only runs once
            $body.off('mousedown touchstart', detectMouse);
        }
        // attach both events to body
        $body.on('mousedown touchstart', detectMouse);
    });
    

    这对我有效

    链接地址: http://www.djcxy.com/p/74139.html

    上一篇: Detecting that the browser has no mouse and is touch

    下一篇: Browser detection in JavaScript?