如何使用JavaScript最佳地检测“触屏”设备?

525

我编写了一个适用于桌面和移动设备的jQuery插件。我想知道是否有一种JavaScript方法可以检测设备是否具有触摸屏功能。我正在使用jquery-mobile.js来检测触摸屏事件,并且它在iOS、Android等设备上工作正常,但是我还想编写基于用户设备是否具有触摸屏的条件语句。

这种可能性存在吗?


这是更好的方法 var x = 'touchstart' in document.documentElement; console.log(x) // 如果支持,则返回true // 否则返回false - Risa__B
为什么即使有新技术出现,这个线程还是被保护了呢? - Andy Hoffman
38个回答

4

看起来Chrome 24现在支持触摸事件,可能是为了Windows 8。因此,这里发布的代码不再有效。现在我不再尝试检测浏览器是否支持触摸,而是绑定触摸和点击事件,并确保只调用其中一个:

myCustomBind = function(controlName, callback) {

  $(controlName).bind('touchend click', function(e) {
    e.stopPropagation();
    e.preventDefault();

    callback.call();
  });
};

然后调用它:

myCustomBind('#mnuRealtime', function () { ... });

希望这能帮到你!

1
相关线程,https://dev59.com/hWcs5IYBdhLWcg3w0HEa - Air

4

除了桌面版 Firefox 之外,所有浏览器都支持响应式设计。这是因为 Firefox 桌面版会支持开发者使用触摸按钮进行响应式设计。

希望 Mozilla 在下一个版本中能够解决这个问题。

我正在使用 Firefox 28 桌面版。

function isTouch()
{
    return !!("ontouchstart" in window) || !!(navigator.msMaxTouchPoints);
}

它仍然是32.0版本,他们还没有修复它!太疯狂了。为什么不能切换呢?这总是返回“true”:( - vsync

4

现在有一个关于检测触摸/非触摸设备的大规模讨论。窗口平板电脑的数量和尺寸正在增加,这给我们网页开发人员带来了另一组麻烦。

我已经使用并测试了blmstr的答案来创建一个菜单。该菜单工作方式如下:当页面加载时,脚本会检测这是触摸还是非触摸设备。根据这个,菜单将使用悬停(非触摸)或点击/轻敲(触摸)进行操作。

在大多数情况下,blmstr的脚本似乎都可以正常工作(特别是2018年的版本)。但是仍然存在某些设备会被错误地检测为触摸设备或非触摸设备。

因此,我进行了一些调查,并且感谢这篇文章,我用其中的几行代码替换了blmstr第四个脚本中的代码:

function is_touch_device4() {
    if ("ontouchstart" in window)
        return true;

    if (window.DocumentTouch && document instanceof DocumentTouch)
        return true;


    return window.matchMedia( "(pointer: coarse)" ).matches;
}

alert('Is touch device: '+is_touch_device4());
console.log('Is touch device: '+is_touch_device4());

因为封锁的原因,我们测试这个设备的触摸装置的供应有限,但到目前为止以上工作得很好。
如果有任何使用桌面触摸装置(例如Surface平板电脑)的人能够确认脚本是否正常工作,我会非常感激。
就支持指针而言,粗略媒体查询似乎得到了支持。我保留了上面的行,因为在移动版Firefox上出了问题,但是媒体查询上面的行就足够了。
谢谢。

为了捕捉移动版Firefox,您可以将以下内容添加到媒体查询中。(-moz-touch-enabled: 1) - dbquarrel

4

jQuery v1.11.3

提供的答案中有很多有用的信息。但是,最近我花了很多时间尝试将所有内容结合起来,以实现两个目标:

  1. 检测正在使用的设备是否为触摸屏类型设备。
  2. 检测设备是否被点击。

除了这篇文章和Detecting touch screen devices with Javascript之外,我还发现Patrick Lauke的这篇文章非常有帮助:https://hacks.mozilla.org/2013/04/detecting-touch-its-the-why-not-the-how/

以下是代码...

$(document).ready(function() {
//The page is "ready" and the document can be manipulated.

    if (('ontouchstart' in window) || (navigator.maxTouchPoints > 0) || (navigator.msMaxTouchPoints > 0))
    {
      //If the device is a touch capable device, then...
      $(document).on("touchstart", "a", function() {

        //Do something on tap.

      });
    }
    else
    {
      null;
    }
});

重要! *.on( events [, selector ] [, data ], handler ) 方法需要一个选择器,通常是一个元素,可以处理“touchstart”事件或与触摸相关的任何其他事件。在这种情况下,它是超链接元素“a”。

现在,您不需要在JavaScript中处理常规鼠标点击,因为您可以使用CSS来使用超链接“a”元素的选择器来处理这些事件,如下所示:

/* unvisited link */
a:link 
{

}

/* visited link */
a:visited 
{

}

/* mouse over link */
a:hover 
{

}

/* selected link */
a:active 
{

}

注意:还有其他选择器...

3

我使用:

if(jQuery.support.touch){
    alert('Touch enabled');
}

在jQuery mobile 1.0.1中


3
var isTouchScreen = 'createTouch' in document;

或者
var isTouchScreen = 'createTouch' in document || screen.width <= 699 || 
    ua.match(/(iPhone|iPod|iPad)/) || ua.match(/BlackBerry/) || 
    ua.match(/Android/);

我想可能需要进行更全面的检查。

3
需要注意的是,ua指的是navigator.userAgent。此外,如果有人在非全屏模式下打开浏览器,则通过屏幕宽度进行检测可能会产生错误的结果。 - HoLyVieR

3
你可以安装modernizer并使用简单的触摸事件。这非常有效,并且在我测试过的每个设备上都有效,包括Windows Surface!
我已经创建了一个jsFiddle
function isTouchDevice(){
    if(Modernizr.hasEvent('touchstart') || navigator.userAgent.search(/Touch/i) != -1){
         alert("is touch");
            return true;
         }else{
            alert("is not touch");
            return false;
    }
}

3
欢迎来到SO! 仅有代码(如未注释的代码)很少构成答案。您可以通过添加片段的解释来改进此答案。 - ebarr

2
实际上,一个考虑上下文的答案似乎是最实用的:
1)公共站点(无需登录):编写UI以同时使用这两个选项。
2)登录站点:捕获鼠标移动是否发生在登录表单上,并将其保存到隐藏输入中。该值随着登录凭据一起传递并添加到用户的会话中,因此可以在会话期间使用。
仅在登录页面添加JQuery代码:
$('#istouch').val(1); // <-- value will be submitted with login form

if (window.addEventListener) {
    window.addEventListener('mousemove', function mouseMoveListener(){
        // Update hidden input value to false, and stop listening
        $('#istouch').val(0); 
        window.removeEventListener('mousemove', mouseMoveListener);
    });
} 

(@Dave Burt和@Martin Lantzsch的答案都很不错)


2

我在尝试使用不同的方法来检测Javascript中当前页面是否正在使用触摸屏设备时遇到了很多困难。

就我目前所知,没有真正可靠的选项可以正确地检测这一属性。浏览器要么在桌面机器上报告触摸事件(因为操作系统可能支持触摸),要么一些解决方案不能在所有移动设备上运行。

最终,我意识到我从一开始就走错了路:

如果我的页面在触摸和非触摸设备上看起来类似,也许我根本不需要担心检测属性: 我的情景是在触摸设备上禁用工具提示,因为它们会导致双击,而我想要单击来激活按钮。

我的解决方案是重构视图,以便不需要在按钮上使用工具提示,最终我不需要使用具有所有缺点的Javascript方法来检测触摸设备。


0

当鼠标连接时,可以假设用户在页面准备好后移动了鼠标至少一点距离 - 没有任何点击。下面的机制检测到这一点。如果检测到,我认为这是缺少触摸支持的迹象,或者如果支持,则在使用鼠标时不太重要。如果未检测到,则假定为触摸设备。

编辑 这种方法可能不适用于所有目的。它可以用于控制基于加载页面上的用户交互激活的功能,例如图像查看器。如今,代码将在没有鼠标的设备上保留mousemove事件绑定。其他方法可能更好。

大致上,它是这样的(抱歉使用jQuery,但在纯JavaScript中类似):

var mousedown, first, second = false;
var ticks = 10;
$(document).on('mousemove', (function(e) {
    if(UI.mousechecked) return;
    if(!first) {
        first = e.pageX;
        return;
        }
    if(!second && ticks-- === 0) {
        second = e.pageX;
        $(document).off('mousemove'); // or bind it to somewhat else
        }
    if(first  && second  && first !== second && !mousedown){
        // set whatever flags you want
        UI.hasmouse = true;
        UI.touch = false;
        UI.mousechecked = true;
    }

    return;
}));
$(document).one('mousedown', (function(e) {
    mousedown = true;
    return;
}));
$(document).one('mouseup', (function(e) {
    mousedown = false;
    return;
}));

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接