如何使用jQuery检测移动设备

1946

有没有一种方法可以在jQuery中检测用户是否使用移动设备?类似于CSS的 @media 属性?如果浏览器在手持设备上,则我想运行不同的脚本。

jQuery的$.browser函数并不是我要找的内容。


8
为移动设备提供专门的移动设备URL。这是大多数主要网站处理移动设备的方式。请参见http://m.google.com。 - user229044
6
jQuery不能做所有的事情,它提供了跨浏览器的DOM遍历和操作、简单的动画和浏览器之间的ajax,并创建了插件开发的框架。在要求jQuery解决方案之前,请注意jQuery的局限性。 - Yi Jiang
87
用户代理是不断变化的目标,阅读本帖的所有人都应该非常警惕用户代理嗅探。 - Rob
57
什么是“移动”设备?它是否支持触摸(包括Chrome Pixel和带鼠标的Windows 8笔记本电脑)?它是否是具有小屏幕的设备(那么视网膜iPad呢)?它是否具有较慢的CPU?还是具有较慢的互联网连接?根据你想要做什么,答案会有所不同。针对屏幕分辨率或触摸进行定位很容易。如果您想为某些设备提供较小的内容或更少的JS,则没有银弹可言。测试window.navigator.connection并退回到(恶劣,不良,不建议)userAgent嗅探。以上仅代表个人意见。 - David Gilbertson
6
我明白你的意思。'手机'似乎被用作触摸、慢速CPU、慢速网络和小屏幕的总称。但是,这些都不是完美的假设。我认为单独考虑这些因素将比为某种模糊的“移动”概念而设计会得到更好的产品。因此,我向原帖发出那个问题。 - David Gilbertson
显示剩余12条评论
66个回答

2307
编辑说明:用户代理检测不是现代Web应用程序的推荐技术。请参见下面答案评论以确认此事实。建议使用其中一个答案,使用功能检测和/或媒体查询。

您可以使用简单的JavaScript来检测它,而不是使用jQuery:

if( /Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent) ) {
 // some code..
}

或者您可以将它们结合起来,通过jQuery使其更易于访问...
$.browser.device = (/android|webos|iphone|ipad|ipod|blackberry|iemobile|opera mini/i.test(navigator.userAgent.toLowerCase()));

现在,对于所有高于设备的设备,$.browser将返回"device"
注意:$.browser已在jQuery v1.9.1中被删除。但是,您可以通过使用jQuery迁移插件Code来使用它。
更详细的版本:
var isMobile = false; //initiate as false
// device detection
if(/(android|bb\d+|meego).+mobile|avantgo|bada\/|blackberry|blazer|compal|elaine|fennec|hiptop|iemobile|ip(hone|od)|ipad|iris|kindle|Android|Silk|lge |maemo|midp|mmp|netfront|opera m(ob|in)i|palm( os)?|phone|p(ixi|re)\/|plucker|pocket|psp|series(4|6)0|symbian|treo|up\.(browser|link)|vodafone|wap|windows (ce|phone)|xda|xiino/i.test(navigator.userAgent) 
    || /1207|6310|6590|3gso|4thp|50[1-6]i|770s|802s|a wa|abac|ac(er|oo|s\-)|ai(ko|rn)|al(av|ca|co)|amoi|an(ex|ny|yw)|aptu|ar(ch|go)|as(te|us)|attw|au(di|\-m|r |s )|avan|be(ck|ll|nq)|bi(lb|rd)|bl(ac|az)|br(e|v)w|bumb|bw\-(n|u)|c55\/|capi|ccwa|cdm\-|cell|chtm|cldc|cmd\-|co(mp|nd)|craw|da(it|ll|ng)|dbte|dc\-s|devi|dica|dmob|do(c|p)o|ds(12|\-d)|el(49|ai)|em(l2|ul)|er(ic|k0)|esl8|ez([4-7]0|os|wa|ze)|fetc|fly(\-|_)|g1 u|g560|gene|gf\-5|g\-mo|go(\.w|od)|gr(ad|un)|haie|hcit|hd\-(m|p|t)|hei\-|hi(pt|ta)|hp( i|ip)|hs\-c|ht(c(\-| |_|a|g|p|s|t)|tp)|hu(aw|tc)|i\-(20|go|ma)|i230|iac( |\-|\/)|ibro|idea|ig01|ikom|im1k|inno|ipaq|iris|ja(t|v)a|jbro|jemu|jigs|kddi|keji|kgt( |\/)|klon|kpt |kwc\-|kyo(c|k)|le(no|xi)|lg( g|\/(k|l|u)|50|54|\-[a-w])|libw|lynx|m1\-w|m3ga|m50\/|ma(te|ui|xo)|mc(01|21|ca)|m\-cr|me(rc|ri)|mi(o8|oa|ts)|mmef|mo(01|02|bi|de|do|t(\-| |o|v)|zz)|mt(50|p1|v )|mwbp|mywa|n10[0-2]|n20[2-3]|n30(0|2)|n50(0|2|5)|n7(0(0|1)|10)|ne((c|m)\-|on|tf|wf|wg|wt)|nok(6|i)|nzph|o2im|op(ti|wv)|oran|owg1|p800|pan(a|d|t)|pdxg|pg(13|\-([1-8]|c))|phil|pire|pl(ay|uc)|pn\-2|po(ck|rt|se)|prox|psio|pt\-g|qa\-a|qc(07|12|21|32|60|\-[2-7]|i\-)|qtek|r380|r600|raks|rim9|ro(ve|zo)|s55\/|sa(ge|ma|mm|ms|ny|va)|sc(01|h\-|oo|p\-)|sdk\/|se(c(\-|0|1)|47|mc|nd|ri)|sgh\-|shar|sie(\-|m)|sk\-0|sl(45|id)|sm(al|ar|b3|it|t5)|so(ft|ny)|sp(01|h\-|v\-|v )|sy(01|mb)|t2(18|50)|t6(00|10|18)|ta(gt|lk)|tcl\-|tdg\-|tel(i|m)|tim\-|t\-mo|to(pl|sh)|ts(70|m\-|m3|m5)|tx\-9|up(\.b|g1|si)|utst|v400|v750|veri|vi(rg|te)|vk(40|5[0-3]|\-v)|vm40|voda|vulc|vx(52|53|60|61|70|80|81|83|85|98)|w3c(\-| )|webc|whit|wi(g |nc|nw)|wmlb|wonu|x700|yas\-|your|zeto|zte\-/i.test(navigator.userAgent.substr(0,4))) { 
    isMobile = true;
}

1
我们可以使用 navigator.userAgentData.mobile 吗? - A.Anvarbekov
@A.Anvarbekov 不是最好的解决方案,因为它在许多浏览器上都不受支持。您可以在此处检查: https://developer.mozilla.org/en-US/docs/Web/API/Navigator/userAgentData#browser_compatibility - Mihai
1
请在2023年不要尝试为手机创建单独的网站版本。相反,使用特征检测来确定输入机制和视口大小。User-Agent嗅探是一个可怕的解决方案,而且不具备未来性。 - Jake
1
@Jake,保留这个答案很有用,因为它解释了为什么历史上选择了这个解决方案,并且与其起始注释一起,解释了为什么应该避免使用此解决方案,如果有人认为这是一个好主意。如果删除答案,则可能会有人后来发现这是一个优秀的网站工程方式。但是,它不应标记为正确答案。请大家支持其他答案。 - Andreas detests censorship
3
@Jake,我看到你在多个答案中复制了相同的两个评论。这并不是很有帮助。相反,请提供正确解决方案的链接。无休止地滚动答案,阅读“这是一个令人震惊的解决方案;使用特性检测”并不是那么有用。哪里有解释如何使用特性检测的答案?为什么这些其他答案不够好?它们在什么情况下不起作用? - Andreas detests censorship
显示剩余2条评论

661

对我而言,小就是美,所以我使用了以下技巧:

CSS 文件中:

/* Smartphones ----------- */
@media only screen and (max-width: 760px) {
  #some-element { display: none; }
}

在 jQuery/JavaScript 文件中:

$( document ).ready(function() {      
    var is_mobile = false;

    if( $('#some-element').css('display')=='none') {
        is_mobile = true;       
    }

    // now I can use is_mobile to run javascript conditionally

    if (is_mobile == true) {
        //Conditional script here
    }
 });

我的目标是让我的网站“移动友好”。因此,我使用CSS Media Queries根据屏幕尺寸显示/隐藏元素。

例如,在我的移动版本中,我不想激活Facebook Like Box,因为它会加载所有那些个人资料图片等东西。这对于移动访问者来说不好。因此,除了隐藏容器元素外,我还在jQuery代码块(上面)中执行以下操作:

if(!is_mobile) {
    (function(d, s, id) {
        var js, fjs = d.getElementsByTagName(s)[0];
        if (d.getElementById(id)) return;
        js = d.createElement(s); js.id = id;
        js.src = "//connect.facebook.net/pt_PT/all.js#xfbml=1&appId=210731252294735";
        fjs.parentNode.insertBefore(js, fjs);
    }(document, 'script', 'facebook-jssdk'));
}

你可以在http://lisboaautentica.com上看到它的实际效果。

我仍然在开发移动版本,所以在撰写本文时,它看起来还不太理想。

dekin88 更新:

JavaScript API内置了一个用于检测媒体的功能。不要使用上述解决方案,而是使用以下内容:

$(function() {      
    let isMobile = window.matchMedia("only screen and (max-width: 760px)").matches;

    if (isMobile) {
        //Conditional script here
    }
 });

浏览器支持: http://caniuse.com/#feat=matchmedia

这种方法的优点是它不仅更简单更短,而且如果有需要,你可以有条件地单独针对智能手机和平板电脑等不同设备进行定位,而无需向DOM添加任何虚拟元素。


85
screen.width 属性是全局的。没有必要随意向 DOM 添加元素并不必要地引入 CSS 媒体查询。此外,如果浏览器在桌面上并且用户调整窗口大小,则 $is_mobile 不会更新。 - merv
130
为什么不这样写:if( screen.width <= 480 ) { // 是移动设备 } - andrewrjones
95
你刚刚重新发明了window.matchMedia:https://developer.mozilla.org/zh-CN/docs/Web/API/Window/matchMedia - Paul Irish
Bootstrap/jQuery 技术非常优秀,如果将其放入函数中,则效果更佳。只需要在屏幕方向更改或尺寸更改时调用即可。 - The concise
这在横屏模式下会出现问题(Pixel 5,Firefox和Chrome)。我建议像这样进行编辑:window.matchMedia('only screen and ((max-width: 767px) or (max-height: 767px))').matches - Zach
显示剩余2条评论

295

尽管 Mozilla使用用户代理进行浏览器检测现在建议不要使用此解决方案:

注意:值得重申的是:使用用户代理嗅探很少是一个好主意。您几乎总能找到更好、更广泛兼容的方法来解决您的问题!

它曾建议:

综上所述,我们建议在用户代理中搜索字符串“Mobi”以检测移动设备。

像这样:

if (/Mobi/.test(navigator.userAgent)) {
    // mobile!
}

这将匹配所有常见的移动浏览器用户代理,包括移动版Mozilla、Safari、IE、Opera、Chrome等。

Android更新

EricL建议还要测试Android作为用户代理,因为平板电脑的Chrome用户代理字符串不包括"Mobi"(但手机版本则包括):

if (/Mobi|Android/i.test(navigator.userAgent)) {
    // mobile!
}

15
这篇文章提到:如果设备足够大,没有标有“Mobi”,则应提供桌面站点(最佳做法是支持触摸输入,因为越来越多的台式机配备了触摸屏)。请注意,不改变原意,并使内容更通俗易懂。 - Daniel Hanrahan
2
请在2023年不要尝试为手机创建单独的网站版本。相反,使用特征检测来确定输入机制和视口大小。User-Agent嗅探是一个可怕的解决方案,而且不具备未来性。 - Jake
能否请给这个回答点赞的296位用户撤销他们的点赞?这是一个令人震惊的回答,也是解决问题的可行方案之外的糟糕选择。或者@QuasarDonkey可以直接点击“删除”按钮,帮助让网络变得更好。 - Jake
如果你需要支持“Opera Mini”(希望不是这种情况),那么你必须在正则表达式中准确地包含它,因为用户代理既不包含“Mobi”也不包含“Android”。 - RiZKiT

109

一个简单而有效的一行代码:

function isMobile() { return ('ontouchstart' in document.documentElement); }

然而,上述代码没有考虑带有触摸屏的笔记本电脑的情况。 因此,我提供了这个基于@Julian的解决方案的第二个版本:

function isMobile() {
  try{ document.createEvent("TouchEvent"); return true; }
  catch(e){ return false; }
}

38
带有触摸屏的Windows笔记本电脑怎么样? - Chris Cinelli
14
你提供的第二个 isMobile 函数在我台式机设备上返回了 true!!(使用 Google Chrome v44.0) - Luke
22
这更像是一个isTouchSupported方法,而不是真正的移动设备检测。 - Barkermn01

74

这不是jQuery,但我找到了这个网站:http://detectmobilebrowser.com/

它提供多种语言的脚本来检测移动浏览器,其中包括JavaScript。这可能会帮助您找到您要寻找的内容。

然而,由于您正在使用jQuery,您可能想了解一下jQuery.support集合。这是一个用于检测当前浏览器功能的属性集合。文档在此处:http://api.jquery.com/jQuery.support/

由于我不知道您要实现什么,所以我不知道哪一个最有用。

话虽如此,我认为你最好的选择是使用服务器端语言重定向或编写不同的输出脚本(如果可行)。由于您真的不知道移动浏览器x的功能,因此在服务器端进行检测和修改逻辑将是最可靠的方法。当然,如果无法使用服务器端语言,则所有这些都是无意义的 :)


14
那里有一个jQuery版本,它运行得非常完美,但是如果要检测平板电脑,你必须像关于部分所描述的那样添加|android|ipad|playbook|silk(这是设计上的需要)。 - cprcrack

50

有时候希望知道客户端正在使用哪个品牌的设备,以便显示特定于该设备的内容,例如链接到iPhone商店或Android市场。Modernizer很不错,但只会显示浏览器的功能,例如HTML5或Flash。

以下是我在jQuery中使用UserAgent解决方案来为每个设备类型显示不同类的方法:

/*** sniff the UA of the client and show hidden div's for that device ***/
var customizeForDevice = function(){
    var ua = navigator.userAgent;
    var checker = {
      iphone: ua.match(/(iPhone|iPod|iPad)/),
      blackberry: ua.match(/BlackBerry/),
      android: ua.match(/Android/)
    };
    if (checker.android){
        $('.android-only').show();
    }
    else if (checker.iphone){
        $('.idevice-only').show();
    }
    else if (checker.blackberry){
        $('.berry-only').show();
    }
    else {
        $('.unknown-device').show();
    }
}

这个解决方案来自 Graphics Maniacs http://graphicmaniacs.com/note/detecting-iphone-ipod-ipad-android-and-blackberry-browser-with-javascript-and-php/


47

在此找到解决方案:http://www.abeautifulsite.net/blog/2011/11/detecting-mobile-devices-with-javascript/

var isMobile = {
    Android: function() {
        return navigator.userAgent.match(/Android/i);
    },
    BlackBerry: function() {
        return navigator.userAgent.match(/BlackBerry/i);
    },
    iOS: function() {
        return navigator.userAgent.match(/iPhone|iPad|iPod/i);
    },
    Opera: function() {
        return navigator.userAgent.match(/Opera Mini/i);
    },
    Windows: function() {
        return navigator.userAgent.match(/IEMobile/i);
    },
    any: function() {
        return (isMobile.Android() || isMobile.BlackBerry() || isMobile.iOS() || isMobile.Opera() || isMobile.Windows());
    }
};

然后,要验证它是否是移动设备,您可以使用以下测试:

if(isMobile.any()) {
   //some code...
}

32

如果您所说的“移动设备”指的是“小屏幕”,我会使用以下代码:

var windowWidth = window.screen.width < window.outerWidth ?
                  window.screen.width : window.outerWidth;
var mobile = windowWidth < 500;

在 iPhone 上,你会得到一个 window.screen.width 的值为 320。在 Android 上,你会得到一个 window.outerWidth 的值为 480(尽管这可能取决于具体的 Android 设备)。iPad 和 Android 平板电脑将返回像 768 这样的数字,所以它们将获得完整的视图,就像你想要的那样。


1
windowWidth 可以设置为 Math.min(window.screen.width, window.outerWidth),以使阅读更加容易。 - Sreenikethan I

31

用一行JavaScript代码实现:

var isMobile = ('ontouchstart' in document.documentElement && /mobi/i.test(navigator.userAgent));
如果用户代理包含“Mobi”(根据MDN的说法),并且ontouchstart可用,则可能是移动设备。 编辑:根据评论中的反馈更新正则表达式代码。使用正则表达式/mobi/i,i使其不区分大小写,mobi匹配所有移动浏览器。请参阅https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/User-Agent/Firefox

22

我知道这个问题有很多答案,但从我看到的来看,没有人像我解决这个问题的方式一样。

CSS使用宽度(媒体查询)来确定基于宽度在Web文档中应用哪些样式。 为什么不在JavaScript中使用宽度呢?

例如,在Bootstrap的(移动设备优先)媒体查询中,存在4个断点:

  • 超小型设备在768个像素及以下。
  • 小型设备范围在768到991个像素之间。
  • 中型设备范围在992到1199个像素之间。
  • 大型设备为1200像素及以上。

我们也可以使用这个来解决我们的JavaScript问题。

首先,我们将创建一个函数,获取窗口大小并返回一个值,以便我们可以查看查看我们的应用程序正在使用哪种设备大小:

var getBrowserWidth = function(){
    if(window.innerWidth < 768){
        // Extra Small Device
        return "xs";
    } else if(window.innerWidth < 991){
        // Small Device
        return "sm"
    } else if(window.innerWidth < 1199){
        // Medium Device
        return "md"
    } else {
        // Large Device
        return "lg"
    }
};

现在我们已经设置好了函数,可以调用它并存储值:

var device = getBrowserWidth();

您的问题是:

如果浏览器在手持设备上,则我想运行不同的脚本。

既然我们已经有了设备信息,那么只剩下一个条件语句:

if(device === "xs"){
  // Enter your script for handheld devices here 
}

下面是CodePen的一个示例:http://codepen.io/jacob-king/pen/jWEeWG


这对我来说效果最好。由于我在一些移动端页面中使用了bootstrap,这种技术可以很好地自动重定向到非移动端(非bootstrap)页面上。提示:我在IE11 F12工具中发现了一个小问题:我在F12开发工具中为移动设备打开了仿真模式,但它无法检测窗口大小。我已经将其调整到xs断点以下,但它仍然检测为md。当我关闭手机仿真并刷新页面时,它正确地检测到了大小,并且在我的代码中我会重定向到一个bootstrap页面。 - Jeff Mergler
2
@JacobKing 你说“小型设备的范围从768到991像素。”这意味着应该是window.innerWidth < 992(包括991)。同样的,对于1199,它应该是<1200而不是。 - medBouzid

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