Javascript 检测移动浏览器

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/11381673/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-24 05:40:12  来源:igfitidea点击:

Detecting a mobile browser

javascriptbrowser-detectionmobile-browserplatform-detection

提问by ave

I'm looking for a function which return boolean value if user has mobile browser or not.

如果用户有移动浏览器,我正在寻找一个返回布尔值的函数。

I know that I can use navigator.userAgentand write that function by using regex, but user-agents are too various for different platforms. I doubt that match all possible devices would be easy, and I think this problem has been solved before many times so there should be some kind of complete solution for such task.

我知道我可以navigator.userAgent通过使用正则表达式来使用和编写该函数,但是用户代理对于不同的平台来说太多样化了。我怀疑匹配所有可能的设备会很容易,我认为这个问题已经解决了很多次,所以应该有某种完整的解决方案来完成这样的任务。

I was looking at this site, but sadly the script is so cryptic that I have no idea how to use it for my purpose, which is to create a function which return true / false.

我正在查看这个站点,但遗憾的是脚本是如此神秘,以至于我不知道如何将它用于我的目的,即创建一个返回 true/false 的函数。

回答by Michael Zaporozhets

Using Regex (from detectmobilebrowsers.com):

使用正则表达式(来自detectmobilebrowsers.com):

Here's a function that uses an insanely long and comprehensive regex which returns a trueor falsevalue depending on whether or not the user is browsing with a mobile.

这是一个函数,它使用一个非常长且全面的正则表达式,它根据用户是否正在使用移动设备浏览来返回 atruefalse值。

window.mobileCheck = function() {
  let check = false;
  (function(a){if(/(android|bb\d+|meego).+mobile|avantgo|bada\/|blackberry|blazer|compal|elaine|fennec|hiptop|iemobile|ip(hone|od)|iris|kindle|lge |maemo|midp|mmp|mobile.+firefox|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|xda|xiino/i.test(a)||/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(a.substr(0,4))) check = true;})(navigator.userAgent||navigator.vendor||window.opera);
  return check;
};

For those wishing to include tablets in this test (though arguably, you shouldn't), you can use the following function:

对于那些希望在此测试中包含平板电脑的人(尽管可以说,您不应该),您可以使用以下功能:

window.mobileAndTabletCheck = function() {
  let check = false;
  (function(a){if(/(android|bb\d+|meego).+mobile|avantgo|bada\/|blackberry|blazer|compal|elaine|fennec|hiptop|iemobile|ip(hone|od)|iris|kindle|lge |maemo|midp|mmp|mobile.+firefox|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|xda|xiino|android|ipad|playbook|silk/i.test(a)||/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(a.substr(0,4))) check = true;})(navigator.userAgent||navigator.vendor||window.opera);
  return check;
};


The Original Answer

原始答案

You can do this by simply running through a list of devices and checking if the useragentmatches anything like so:

您可以通过简单地浏览设备列表并检查是否useragent匹配以下内容来完成此操作:

  function detectMob() {
    const toMatch = [
        /Android/i,
        /webOS/i,
        /iPhone/i,
        /iPad/i,
        /iPod/i,
        /BlackBerry/i,
        /Windows Phone/i
    ];

    return toMatch.some((toMatchItem) => {
        return navigator.userAgent.match(toMatchItem);
    });
}

However since you believe that this method is unreliable, You could assume that any device that had a resolution of 800x600or less was a mobile device too, narrowing your target even more (although these days many mobile devices have much greater resolutions than this)

但是,由于您认为此方法不可靠,因此您可以假设任何分辨率为800x600或更低的设备也是移动设备,从而进一步缩小您的目标范围(尽管如今许多移动设备的分辨率远高于此)

i.e

IE

  function detectMob() {
    return ( ( window.innerWidth <= 800 ) && ( window.innerHeight <= 600 ) );
  }

Reference:

参考:

回答by yoav barnea

How about:

怎么样:

if (typeof window.orientation !== 'undefined') { ... }

...since smartphones usually support this property and desktop browsers don't.

...因为智能手机通常支持此属性而桌面浏览器不支持。

EDIT:As @Gajus pointed out, this solution is now deprecated and shouldn't be used (https://developer.mozilla.org/en-US/docs/Web/API/Window/orientation)

编辑:正如@Gajus 指出的,此解决方案现已弃用,不应使用(https://developer.mozilla.org/en-US/docs/Web/API/Window/orientation

回答by Mudaser Ali

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) || navigator.userAgent.match(/WPDesktop/i);
    },
    any: function() {
        return (isMobile.Android() || isMobile.BlackBerry() || isMobile.iOS() || isMobile.Opera() || isMobile.Windows());
    }
};

How to use

如何使用

if( isMobile.any() ) alert('Mobile');

To check to see if the user is on a specific mobile device:

要检查用户是否在特定的移动设备上:

if( isMobile.iOS() ) alert('iOS');

Ref: http://www.abeautifulsite.net/blog/2011/11/detecting-mobile-devices-with-javascript

参考:http: //www.abeautifulsite.net/blog/2011/11/detecting-mobile-devices-with-javascript

Enhanced version on github : https://github.com/smali-kazmi/detect-mobile-browser

github 上的增强版:https: //github.com/smali-kazmi/detect-mobile-browser

回答by Santhosh

Here is a simple solution from the source of facebook's slingshot

这是来自facebook的弹弓来源的一个简单解决方案

var isMobile = /iPhone|iPad|iPod|Android/i.test(navigator.userAgent);
if (isMobile) {
  /* your code here */
}

回答by Tigger

Came here looking for a simple, clean way to detect "touch screens devices", which I class as mobile and tablets. Did not find a clean choice in the current answers but did work out the following which may also help someone.

来到这里寻找一种简单、干净的方法来检测“触摸屏设备”,我将其归类为移动设备和平板电脑。在当前的答案中没有找到一个干净的选择,但确实解决了以下问题,这也可能对某人有所帮助。

var touchDevice = ('ontouchstart' in document.documentElement);

Edit: To support desktops with a touch screen and mobiles at the same time you can use the following:

编辑:要同时支持带有触摸屏和手机的台式机,您可以使用以下内容:

var touchDevice = (navigator.maxTouchPoints || 'ontouchstart' in document.documentElement);

回答by gsxrboy73

As many have stated, relying on the moving target of the user agent data is problematic. The same can be said for counting on screen size.

正如许多人所说,依赖用户代理数据的移动目标是有问题的。计算屏幕尺寸也是如此。

My approach is borrowed from a CSS techniqueto determine if the interface is touch:

我的方法是借用CSS 技术来确定界面是否是触摸的:

Using only javascript (support by all modern browsers), a media querymatch can easily infer whether the device is mobile.

仅使用 javascript(所有现代浏览器都支持),媒体查询匹配可以轻松推断设备是否是mobile

function isMobile() {
    var match = window.matchMedia || window.msMatchMedia;
    if(match) {
        var mq = match("(pointer:coarse)");
        return mq.matches;
    }
    return false;
}

回答by TheDarkIn1978

According to MDN's article on Browser detection using the user agent, it is encouraged to avoid this approach if possible and suggest other avenues such as feature detection.

根据MDN 关于使用用户代理进行浏览器检测的文章,鼓励尽可能避免这种方法,并建议其他途径,例如特征检测。

However, if one must use the user agent as a means to detect if the device is mobile, they suggest:

但是,如果必须使用用户代理作为检测设备是否可移动的手段,他们建议:

In summary, we recommend looking for the string “Mobi” anywhere in the User Agent to detect a mobile device.

总之,我们建议在用户代理中的任何位置查找字符串“Mobi”以检测移动设备。

Therefore, this one-liner will suffice:

因此,这种单线就足够了:

const isMobileDevice = window.navigator.userAgent.toLowerCase().includes("mobi");

const isMobileDevice = window.navigator.userAgent.toLowerCase().includes("mobi");

[UPDATE]:

[更新]:

As @zenw0lf suggests in the comments, using a Regular Expression would be better:

正如@zenw0lf 在评论中所建议的那样,使用正则表达式会更好:

const isMobileDevice = /Mobi/i.test(window.navigator.userAgent)

const isMobileDevice = /Mobi/i.test(window.navigator.userAgent)

回答by John Slegers

There's no perfect solution for detecting whether JS code is executed on a mobile browser, but the following two options should work in most cases.

检测 JS 代码是否在移动浏览器上执行没有完美的解决方案,但以下两个选项在大多数情况下应该有效。

Option 1 : browser sniffing

选项 1:浏览器嗅探

!function(a){var b=/iPhone/i,c=/iPod/i,d=/iPad/i,e=/(?=.*\bAndroid\b)(?=.*\bMobile\b)/i,f=/Android/i,g=/(?=.*\bAndroid\b)(?=.*\bSD4930UR\b)/i,h=/(?=.*\bAndroid\b)(?=.*\b(?:KFOT|KFTT|KFJWI|KFJWA|KFSOWI|KFTHWI|KFTHWA|KFAPWI|KFAPWA|KFARWI|KFASWI|KFSAWI|KFSAWA)\b)/i,i=/IEMobile/i,j=/(?=.*\bWindows\b)(?=.*\bARM\b)/i,k=/BlackBerry/i,l=/BB10/i,m=/Opera Mini/i,n=/(CriOS|Chrome)(?=.*\bMobile\b)/i,o=/(?=.*\bFirefox\b)(?=.*\bMobile\b)/i,p=new RegExp("(?:Nexus 7|BNTV250|Kindle Fire|Silk|GT-P1000)","i"),q=function(a,b){return a.test(b)},r=function(a){var r=a||navigator.userAgent,s=r.split("[FBAN");return"undefined"!=typeof s[1]&&(r=s[0]),s=r.split("Twitter"),"undefined"!=typeof s[1]&&(r=s[0]),this.apple={phone:q(b,r),ipod:q(c,r),tablet:!q(b,r)&&q(d,r),device:q(b,r)||q(c,r)||q(d,r)},this.amazon={phone:q(g,r),tablet:!q(g,r)&&q(h,r),device:q(g,r)||q(h,r)},this.android={phone:q(g,r)||q(e,r),tablet:!q(g,r)&&!q(e,r)&&(q(h,r)||q(f,r)),device:q(g,r)||q(h,r)||q(e,r)||q(f,r)},this.windows={phone:q(i,r),tablet:q(j,r),device:q(i,r)||q(j,r)},this.other={blackberry:q(k,r),blackberry10:q(l,r),opera:q(m,r),firefox:q(o,r),chrome:q(n,r),device:q(k,r)||q(l,r)||q(m,r)||q(o,r)||q(n,r)},this.seven_inch=q(p,r),this.any=this.apple.device||this.android.device||this.windows.device||this.other.device||this.seven_inch,this.phone=this.apple.phone||this.android.phone||this.windows.phone,this.tablet=this.apple.tablet||this.android.tablet||this.windows.tablet,"undefined"==typeof window?this:void 0},s=function(){var a=new r;return a.Class=r,a};"undefined"!=typeof module&&module.exports&&"undefined"==typeof window?module.exports=r:"undefined"!=typeof module&&module.exports&&"undefined"!=typeof window?module.exports=s():"function"==typeof define&&define.amd?define("isMobile",[],a.isMobile=s()):a.isMobile=s()}(this);

alert(isMobile.any ? 'Mobile' : 'Not mobile');

This particular browser sniffing code is that of a library called isMobile.

这个特定的浏览器嗅探代码是一个名为 isMobile 的库的代码。



Option 2 : window.orientation

选项 2:window.orientation

Test if window.orientationis defined :

测试是否window.orientation定义:

var isMobile = window.orientation > -1;
alert(isMobile ? 'Mobile' : 'Not mobile');



Note

笔记

Not all touchscreen devices are mobile and vice versa. So, if you want to implement something specifically for touchscreen, you shouldn't test if your browser is run on a mobile device but rather whether the devices has touchscreen support :

并非所有触摸屏设备都是移动设备,反之亦然。所以,如果你想实现一些专门针对触摸屏的东西,你不应该测试你的浏览器是否在移动设备上运行,而应该测试设备是否支持触摸屏:

var hasTouchscreen = 'ontouchstart' in window;
alert(hasTouchscreen ? 'has touchscreen' : 'doesn\'t have touchscreen');

回答by JeffJak

Here is a userAgent solution that is more efficent than match...

这是一个比匹配更有效的 userAgent 解决方案......

function _isMobile(){
    // if we want a more complete list use this: http://detectmobilebrowsers.com/
    // str.test() is more efficent than str.match()
    // remember str.test is case sensitive
    var isMobile = (/iphone|ipod|android|ie|blackberry|fennec/).test
         (navigator.userAgent.toLowerCase());
    return isMobile;
}

回答by Rasmus S?borg

To add an extra layer of control I use the HTML5 storage to detect if it is using mobile storage or desktop storage. If the browser does not support storage I have an array of mobile browser names and I compare the user agent with the browsers in the array.

为了添加额外的控制层,我使用 HTML5 存储来检测它是使用移动存储还是桌面存储。如果浏览器不支持存储,我有一个移动浏览器名称数组,并将用户代理与数组中的浏览器进行比较。

It is pretty simple. Here is the function:

这很简单。这是函数:

// Used to detect whether the users browser is an mobile browser
function isMobile() {
    ///<summary>Detecting whether the browser is a mobile browser or desktop browser</summary>
    ///<returns>A boolean value indicating whether the browser is a mobile browser or not</returns>

    if (sessionStorage.desktop) // desktop storage 
        return false;
    else if (localStorage.mobile) // mobile storage
        return true;

    // alternative
    var mobile = ['iphone','ipad','android','blackberry','nokia','opera mini','windows mobile','windows phone','iemobile']; 
    for (var i in mobile) if (navigator.userAgent.toLowerCase().indexOf(mobile[i].toLowerCase()) > 0) return true;

    // nothing found.. assume desktop
    return false;
}