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

这可能吗?


当前回答

我使用上面的代码片段来检测是否有触摸,所以我的iframe会在台式电脑上显示,而不是在触摸时显示。我注意到Android 4.0的Opera Mini在单独使用blmstr代码时仍然注册为非触摸设备。(有人知道为什么吗?)

我最终使用:

<script>
$(document).ready(function() {
    var ua = navigator.userAgent;
    function is_touch_device() { 
        try {  
            document.createEvent("TouchEvent");  
            return true;  
        } catch (e) {  
            return false;  
        }  
    }

    if ((is_touch_device()) || ua.match(/(iPhone|iPod|iPad)/) 
    || ua.match(/BlackBerry/) || ua.match(/Android/)) {
        // Touch browser
    } else {
        // Lightbox code
    }
});
</script>

其他回答

我会避免使用屏幕宽度来判断一个设备是否是触控设备。触摸屏比699px大得多,想想Windows 8。Navigatior。userAgent可以很好地覆盖误报。

我建议你在Modernizr上看看这一期。

你是想测试设备是否支持触摸事件,还是一个触摸设备。不幸的是,这不是一回事。

我使用上面的代码片段来检测是否有触摸,所以我的iframe会在台式电脑上显示,而不是在触摸时显示。我注意到Android 4.0的Opera Mini在单独使用blmstr代码时仍然注册为非触摸设备。(有人知道为什么吗?)

我最终使用:

<script>
$(document).ready(function() {
    var ua = navigator.userAgent;
    function is_touch_device() { 
        try {  
            document.createEvent("TouchEvent");  
            return true;  
        } catch (e) {  
            return false;  
        }  
    }

    if ((is_touch_device()) || ua.match(/(iPhone|iPod|iPad)/) 
    || ua.match(/BlackBerry/) || ua.match(/Android/)) {
        // Touch browser
    } else {
        // Lightbox code
    }
});
</script>

试图检测触控的最大“陷阱”是同时支持触控和触控板/鼠标的混合设备。即使你能够正确地检测用户的设备是否支持触摸,你真正需要做的是检测用户当前使用的输入设备。这里有一份关于这个挑战的详细报告和可能的解决方案。

基本上,判断用户是触摸屏幕还是使用鼠标/触控板的方法是在页面上注册touchstart和mouseover事件:

document.addEventListener('touchstart', functionref, false) // on user tap, "touchstart" fires first
document.addEventListener('mouseover', functionref, false) // followed by mouse event, ie: "mouseover"

触摸动作会触发这两个事件,尽管前者(touchstart)在大多数设备上总是先触发。因此,依靠这个可预测的事件序列,您可以创建一种机制,动态地向文档根添加或删除一个can-touch类,以反映当前用户在文档上的输入类型:

;(function(){
    var isTouch = false //var to indicate current input type (is touch versus no touch) 
    var isTouchTimer 
    var curRootClass = '' //var indicating current document root class ("can-touch" or "")
     
    function addtouchclass(e){
        clearTimeout(isTouchTimer)
        isTouch = true
        if (curRootClass != 'can-touch'){ //add "can-touch' class if it's not already present
            curRootClass = 'can-touch'
            document.documentElement.classList.add(curRootClass)
        }
        isTouchTimer = setTimeout(function(){isTouch = false}, 500) //maintain "istouch" state for 500ms so removetouchclass doesn't get fired immediately following a touch event
    }
     
    function removetouchclass(e){
        if (!isTouch && curRootClass == 'can-touch'){ //remove 'can-touch' class if not triggered by a touch event and class is present
            isTouch = false
            curRootClass = ''
            document.documentElement.classList.remove('can-touch')
        }
    }
     
    document.addEventListener('touchstart', addtouchclass, false) //this event only gets called when input type is touch
    document.addEventListener('mouseover', removetouchclass, false) //this event gets called when input type is everything from touch to mouse/ trackpad
})();

详情请点击这里。

关于如何在Javascript中检测页面是否显示在触摸屏设备上,我也遇到了很多困难。 在我看来,到目前为止,还没有真正的选项可以正确地检测这个选项。 浏览器要么报告桌面机器上的触摸事件(因为操作系统可能已经准备好触摸了),要么某些解决方案不能在所有移动设备上工作。

最后,我意识到我从一开始就采取了错误的方法: 如果我的页面在触摸和非触摸设备上看起来相似,我可能根本不需要担心检测属性: 我的方案是禁用触摸设备上的按钮上的工具提示,因为它们会导致双击,而我希望通过一次点击来激活按钮。

我的解决方案是重构视图,这样按钮上就不需要工具提示了,最后我也不需要用Javascript的方法来检测触摸设备了,因为这些方法都有自己的缺点。

var isTouchScreen = 'createTouch' in document;

or

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

我想会进行更彻底的检查。