检测移动浏览器


888

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

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

我当时在看这个站点,但可悲的是脚本太神秘了,以至于我不知道如何使用它来创建一个返回true / false的函数。




5
@Thrustmaster:真的不会。为不同的浏览器提供不同的JS意味着您必须添加Vary: User-Agent响应,否则缓存代理将存储一个版本并将其发送到另一种浏览器。但是Vary: User-Agent使响应无法在IE中进行。
bobince'7

16
@ave:您试图通过检测“移动”浏览器来做什么?在当今的平板电脑和混合计算设备领域,这种区别是非常有争议的。您是否要检测小屏幕并在这种情况下呈现不同的UI?您是否要检测低带宽连接?您是否要检测触摸界面?
bobince'7

2
因此,我已经更新了答案,以使用detectmobilebrowsers.com javascript方法,但如果有人仍然需要此值,则返回一个布尔值。( 以防万一 )。快乐侦探:)
Michael Zaporozhets

Answers:


1316

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

这是一个使用冗长而全面的正则表达式的函数,该正则表达式根据用户是否使用手机浏览返回a truefalse值。

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;
};

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

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;
};

原始答案

您可以通过简单地浏览设备列表并检查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);
    });
}

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

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

参考:


25
嗨,我刚刚在iPad 3(iOS 6.1.2)上访问了detectmobilebrowsers.com链接,并显示“未检测到移动浏览器”。
理查德·洛夫乔伊

49
@RichardLovejoy在构建站点时,通常不将ipad视为移动设备。
Michael Zaporozhets

42
从“ 关于”页面:设计时未检测到Android平板电脑,iPad,Kindle Fires和PlayBooks。要添加对平板电脑的支持,请添加|android|ipad|playbook|silk到第一个正则表达式。
Gras Double

13
Google TV也是Android。什么定义了手机?屏幕尺寸 ?触摸?deviceOrientation?当我设计时,更多的是鼠标悬停,大按钮或小链接的问题。所以,就目前而言,我使用“ if(Modernizr.touch)” :)
molokoloco 2013年

30
高德(Gawd),整个用户代理构想都非常糟糕,确实需要停止。我们确实需要停止让客户反潮流,而只坚持媒体查询。如果他们想根据特定页面的规模进行重定向,则只需通过JS检查特定媒体查询的范围,即tylergaw.com/articles/reacting-to-media-queries-in-javascript
markyzm,2013年

324

怎么样:

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

...因为智能手机通常支持此属性,而台式机浏览器则不支持。

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


14
这实际上是超级独特而且很棒,您介意我将它添加到答案中吗?
Michael Zaporozhets

77
这可能不会持续很长时间。1)平板电脑可以具有不错的屏幕尺寸,您希望它们显示完整的桌面网站,但它们将具有此属性2)Windows 8在这里,一堆笔记本电脑带有触摸屏和旋转屏幕。
戴夫·希尔迪奇

10
至于关于屏幕尺寸合适的平板电脑的第一点,我想您也可以对所有其他解决方案(将大屏幕平板电脑跟踪为小屏幕)做出相同的论点。无论如何,这里的想法是搜索小型设备共享的属性,而不是保留较长的代码,并在每个新的设备/版本/模型中添加正则表达式。我认为设备检测属于过去,而今天我们需要专注于特征检测。再次,我将很高兴在此谈论更合适的房地产……
yoav barnea

2
爱它,完美地工作,谢谢。对于我的解决方案,我只是追求简单。
Bojangles

40
window.orientation不赞成使用性质(developer.mozilla.org/en-US/docs/Web/API/Window/orientationcompat.spec.whatwg.org/#dom-window-orientation)一些移动浏览器选择,原因不明支持。相同的浏览器实现window.screen.orientation(也在桌面浏览器中定义)。我只能假定window.orientation由于遗留原因而留在那儿,因此不应该在新的应用程序中使用。
朱斯

115
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());
    }
};

如何使用

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

要检查用户是否在特定的移动设备上,请执行以下操作:

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

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

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


为什么不对any()ORed isMobile成员进行for ... in循环?
SomeShinyObject 2014年

@ChristopherW我已按照您的建议创建了其插件并修改了代码
Mudaser Ali 2014年

2
也许将iOS移至BlackBerry()之前只是为了将更常见的情况放在首位,并让早期救助计划节省一些额外的处理时间?
Rob_vH 2015年

2
@Rob_vH我已经将此代码添加到具有某些高级功能的github(github.com/smali-kazmi/detect-mobile-browser)中;您也可以在那里发送建议
-Mudaser Ali

1
@AkarshSatija这5个正则表达式检查的性能下降是否会真正影响您的任何应用程序?如果这样做的话,我会感到非常惊讶。过早的优化可能会浪费时间...
trusktr

68

这是来自Facebook弹弓的简单解决方案

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

真好 在某些情况下非常有用
Chuck Le Butt

在检测可以安装移动应用程序的设备的情况下很有用。本质上,您并不关心浏览器。只是设备/操作系统。
查理·里策

30

来到这里寻找一种简单,干净的方法来检测“触摸屏设备”,我将其归类为手机和平板电脑。在当前答案中没有找到一个明智的选择,但做了以下工作,这可能会对某人有所帮助。

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

编辑:要同时支持带触摸屏的桌面和手机,可以使用以下命令:

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

9
如果台式机的显示器支持触摸怎么办?
安东·库兹敏

@HappyCoder我相信这取决于操作系统何时告知浏览器桌面上的触摸屏处于活动状态。因此,是的,该检查仍然有效。
跳跳虎

(+1),但是我现在使用的台式机具有触摸屏,并且与并不总是一致的touchstart|end|etc
科迪

1
引导日期选择器使用以下内容:if(document。window.navigator.msMaxTouchPoints ||'ontouchstart'){this.input.blur(); }
JT Taylor

1
@JTTaylor似乎Microsoft 推荐 navigator.maxTouchPoints(无ms前缀)。还有MDN文章要检查。
跳跳虎

19

如许多人所述,依靠用户代理数据的移动目标是有问题的。指望屏幕大小也可以这样说。

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

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

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

6
带有触摸屏的笔记本电脑怎么样?
Maxim

6
我会检查!matchMedia(“(any-pointer:fine)”)。match我自己。(“没有鼠标插入”,而不是“有一个触摸屏。”
Sora2455

这行得通,但是我的上一个脚本会被使用浏览器缩放功能的人所欺骗(例如,我在一个13英寸屏幕上与4K聊天的人跌落到1080p,但仍必须使用缩放)。在我的iPhone(Safari / Firefox浏览器)和Android设备(Waterfox /镀铬/“浏览器”)当然。很多更可靠高于一切上投票的答案。
约翰

在我为其添加了navigator.userAgent.toLowerCase()。indexOf('fennec')> -1的Android上未检测到FireFox fennec(可能不是最好的补充。)
StayCool

2
另外,您可以测试悬停属性:对于智能手机和触摸屏@media(悬停:无)和(指针:粗糙)
Batailley

16

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

但是,如果必须使用用户代理来检测设备是否可移动,则他们建议:

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

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

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

[更新]:

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

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


.includesIE-11无法提供支持-Pasha
Oleynik

1
@PashaOleynik一个polyfill可以解决这个问题
Maxim

装有Android的Nexus 7平板电脑Mobile的用户代理字符串中没有
Alex Sorokoletov,

@AlexSorokoletov也请参见MDN文章If the device is large enough that it's not marked with “Mobi”, you should serve your desktop site (which, as a best practice, should support touch input anyway, as more desktop machines are appearing with touchscreens).
TheDarkIn1978

1
我认为这可以在没有const isMobile = /Mobi/.test(window.navigator.userAgent)
polyfills的

14

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

选项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');

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


选项2:window.orientation

测试是否window.orientation定义:

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


注意

并非所有触摸屏设备都可以移动,反之亦然。因此,如果您想实现专门用于触摸屏的功能,则不应该测试您的浏览器是否在移动设备上运行,而应该测试这些设备是否具有触摸屏支持:

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


定向方法真的很好!))
Maxim

1
我喜欢您的window.orientation解决方案,但是文档说它已过时了!developer.mozilla.org/en-US/docs/Web/API/Window/orientation
skwidbreth '18

3
定向方法不是很好,因为Windows 8和更高版本可以更改定向。
海特

Windows 8和更高版本专注于增加对移动设备的支持,同时也增加对混合动力(可以转换为大键盘的笔记本电脑)的支持,这就是为什么定向失败作为一种检测方法的原因,即使moz并未将其称为不推荐使用。
杰夫·克莱顿

它来自Win 7,安装了图形软件,可以更改方向,但问自己一个问题,谁可以在台式机/笔记本电脑上使用其他屏幕方向(例如,纵向)而不是横向,并使用i超过1分钟。没有人 !!!更改桌面上的方向意味着您将开始从下到上阅读屏幕上的字符。
GirlCode

11

这是一个比匹配更有效的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;
}

7
测试方法不区分大小写,但是您的正则表达式是区分大小写的。您可以只标记不区分大小写的正则表达式,并在末尾加上“ i”并执行/iphone|etc/i.test(navigator.userAgent)
xec

11

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

这很简单。这是函数:

// 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;
}

3
我尚未在移动设备上进行测试,但是sessionStorage.desktopSafari,Chrome或Firefox(发布时,所有最新版本)都不存在。但是,您会获得投票权,因为您的解决方案比其他解决方案朝着更好的方向发展。但不要忘记使用var mobile =而不是mobile =
shuckster 2013年

3
最好不要在仍不支持该方法的旧版浏览器中使用indexOf,也不要使用polyfill。不必在小写值列表上使用toLowerCase,如果您正在运行/ipad|iphone|etc/i.test(navigator.userAgent)而不是那里的慢循环,也不必这样做。
Jeffrey Gilbert 2014年

10

功能检测比试图弄清楚您正在使用的设备要好得多,并且很难跟上新设备的出现,这非常好,Modernizr之类的库可以让您知道某个特定功能是否可用。


18
您已经回答了另一个问题。您回答的不是“我如何检测到手机?”,而是“我如何检测到某些功能?”。并非所有设备检测都用于功能检测。如果我们要获取有关设备的统计信息怎么办?然后,不,“特征检测”并不“比[修整设备]好得多”。
乔纳森·阿拉德

1
这不是答案,但它不仅仅应该是评论。问题是:为什么您只想检测一个浏览器,然后又可能仅仅因为(缺乏)触摸而想知道它。在大多数情况下(即使不是全部),响应式网页设计也足够了。
Twojr

8

这样的事情怎么样?

if(
    (screen.width <= 640) || 
    (window.matchMedia && 
     window.matchMedia('only screen and (max-width: 640px)').matches
    )
  ){
   // Do the mobile thing
}

为什么不使用它screen.width呢?在我看来,这比更加可靠window.matchMedia
John Slegers '16

约翰说的很好,我不记得当时我在想什么,如果第一个子句为假,那么第二个子句似乎不太可能(现在来看)。我一定添加了它,这一定是有原因的。
stujo

大多数体面的程序员在看到一年前编写的代码时都会感到ham愧。那些不只是成为程序员的人;-)
John Slegers

4
窗口分辨率与浏览器是否在移动设备上无关。例如,许多桌面浏览器在非全屏窗口中运行。如果您为这些浏览器提供了一个专为手持屏幕设计的UI,那么他们的用户将会感到沮丧。
ʇsәɹoɈ

1
@JohnSlegers-我很as愧谷歌搜索一个问题,并在stackoverflow上找到自己的答案。一次又一次。我本人一直处于堆栈溢出状态
vsync

7

元素获得焦点后,立即将其模糊。Bootstrap-datepicker是一个非常受欢迎且维护良好的组件,在GitHub中拥有近10,000个星,它使用以下方法:

if (window.navigator.maxTouchPoints || 'ontouchstart' in document) {
    this.input.blur();
}

https://github.com/uxsolutions/bootstrap-datepicker

感谢Tigger的协助。


7

检测移动设备或平板设备的一种非常好的方法是查看浏览器是否可以创建触摸事件。

纯JavaScript代码:

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

if (isMobile()) {
   # do whatever you wanna do!
}

这对我来说确实很好,但是包括触摸屏显示器的笔记本电脑设备可能存在问题。

我不确定触摸屏笔记本电脑是否会被检测为移动设备,因为我尚未对其进行测试。


5
触摸屏笔记本电脑将被检测为移动设备。以及台式机的触摸屏显示器。信不信由你,如果您正在使用触摸屏设备将RDP放入另一个没有触摸屏的设备,也会遇到问题。
blissfool

@blissfool我猜这不是检测移动设备的正确方法。
新莫里纳

抱歉不行。但是,对于非常有限的用例来说,它仍然可能是一个可行的选择。
blissfool

永远不要编写基于异常的代码,无论如何都要确保抛出该异常……
Pablo

@Sivic仅在TouchEvent不存在并且上面的代码捕获到它并返回false时才引发它。在移动设备或平板电脑或其他触摸屏设备上并非如此。
新莫里纳

5

这是我为该问题重新考虑的解决方案。仍然不完美。唯一正确的解决方案是设备制造商开始认真对待“移动”和“平板电脑”用户代理字符串。

window.onload = userAgentDetect;
function userAgentDetect() {
  if(window.navigator.userAgent.match(/Mobile/i)
  || window.navigator.userAgent.match(/iPhone/i)
  || window.navigator.userAgent.match(/iPod/i)
  || window.navigator.userAgent.match(/IEMobile/i)
  || window.navigator.userAgent.match(/Windows Phone/i)
  || window.navigator.userAgent.match(/Android/i)
  || window.navigator.userAgent.match(/BlackBerry/i)
  || window.navigator.userAgent.match(/webOS/i)) {
    document.body.className += ' mobile';
    alert('True - Mobile - ' + navigator.userAgent);
  } else {
    alert('False - Mobile - ' + navigator.userAgent);
  }
  if(window.navigator.userAgent.match(/Tablet/i)
  || window.navigator.userAgent.match(/iPad/i)
  || window.navigator.userAgent.match(/Nexus 7/i)
  || window.navigator.userAgent.match(/Nexus 10/i)
  || window.navigator.userAgent.match(/KFAPWI/i)) {
    document.body.className -= ' mobile';
    document.body.className += ' tablet';
    alert('True - Tablet - ' + navigator.userAgent);
  } else {
    alert('False - Tablet - ' + navigator.userAgent);
  }
}

如果Nexus 7平板电脑只有Android UA字符串,会发生什么情况?首先,Mobile变为true,随后在Tablet上也变为true,但是Tablet将从body标签中删除Mobile UA字符串。

CSS:

body.tablet { background-color: green; }
body.mobile { background-color: red; }

alert为开发添加了行。Chrome控制台可以模拟许多手持设备。在那测试。

编辑:

只是不要使用它,而是使用特征检测。有太多的设备和品牌,以品牌为目标永远不会是正确的解决方案。


4

我建议您查看http://wurfl.io/

简而言之,如果您导入一个小的JS文件:

<script type='text/javascript' src="//wurfl.io/wurfl.js"></script>

您将得到一个类似于以下内容的JSON对象:

{
 "complete_device_name":"Google Nexus 7",
 "is_mobile":true,
 "form_factor":"Tablet"
}

(当然,假设您使用的是Nexus 7),则可以执行以下操作:

if(WURFL.form_factor == "Tablet"){
    //dostuff();
}

这就是您要寻找的。

免责声明:我为提供这项免费服务的公司工作。谢谢。


1
而且这怎么不识别iPhone上的Safari?
Amyth'9

您可以扩展正在使用的浏览器(精确的UA字符串将是完美的),正在获取的数据以及期望的数据吗?
卡·帕萨尼

我也尝试过wurfl,我在运行IOS 11.2的iPhone 5C上。它无法将Safari识别为移动浏览器。我期望使用“ is_mobile”:true,然后使用“ form_factor”:Smartphone及其不返回。
Mike Wells

我不得不求助于公司的移动数据专家,他们告诉我OS 11.2不能在5C上运行。最低的设备是5S。因此,您编写的内容有误。随时离线与ScientiaMobile联系,以确认断开的位置。谢谢
卡·帕萨尼


3

取决于用例。所有移动设备都需要电池。如果您想要的是在不消耗电池电量的情况下计算电量,请使用Battery Status API

navigator.getBattery().then(battery => {
  battery.charging ? 'charging' : 'not charging';
});

如果您要查找的是presentational use matchMedia,它将返回一个布尔值:

if (window.matchMedia("(min-width: 400px)").matches) {
  /* the viewport is at least 400 pixels wide */
} else {
  /* the viewport is less than 400 pixels wide */
}

或将它们组合在一起,以在平板电脑设备上获得更好的用户体验。


请注意,电池状态API已从浏览器中删除。
Sora2455 '19

Battery Status API已从Firefox中删除,但自2016年7月以来仍是W3C候选推荐书,继续在流行的浏览器中起作用,并且对形成体验很有用
乔什·哈布达斯

2

这是ECMAScript 6解决方案(支持TypeScript)

public isMobile(): boolean {
  let check = false;
  ((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);
  return check;
 }

为什么不只返回if条件而不是拥有整个check变量?
Vic

2

有一个简单的技巧可以检测它是否是移动设备。只需检查ontouchstart事件是否存在:

function isMobile()
{
    return "ontouchstart" in window;
}

3
不适用于笔记本电脑和触摸屏显示器的桌面。混合PC之类的Surface也将成为一个问题。台式机的问题较少,但如今有更多的触摸屏笔记本电脑在销售。
blissfool

2

我遇到了一些上面的答案对我有用的场景。所以我想出了这个。可能对某人有帮助。

if(/iPhone|iPad|iPod|Android|webOS|BlackBerry|Windows Phone/i.test(navigator.userAgent)
 || screen.availWidth < 480){
//code for mobile
}

这取决于您的用例。如果您专注于屏幕使用screen.availWidth,或者可以document.body.clientWidth根据文档进行渲染,则可以使用。


1

最好的必须是:

var isMobile = (/Mobile/i.test(navigator.userAgent));

但是就像Yoav Barnea所说的那样...

// Seem legit
var isMobile = ('DeviceOrientationEvent' in window || 'orientation' in window);
// But with my Chrome on windows, DeviceOrientationEvent == fct()
if (/Windows NT|Macintosh|Mac OS X|Linux/i.test(navigator.userAgent)) isMobile = false;
// My android have "linux" too
if (/Mobile/i.test(navigator.userAgent)) isMobile = true;

经过这3次测试后,我希望var isMobile是...好


> Android上的Firefox移动版似乎在窗口中没有“方向”
molokoloco

1
对不起..对我来说,它现在可以正常工作了。“如果(Modernizr.touch)/ * ... * /”并继续...
molokoloco

只是想知道Modernizr.touch在触摸屏台式设备上如何工作。
B2K

为了使它更加优雅,您应该只在一个if-else if-else if块中编写所有代码。
Heitor

1

这是他的全部功能

function isMobile(){
    return (/(android|bb\d+|meego).+mobile|avantgo|bada\/|blackberry|blazer|compal|elaine|fennec|hiptop|iemobile|ip(hone|od)|iris|kindle|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|android|ipad|playbook|silk/i.test(navigator.userAgent||navigator.vendor||window.opera)||/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||navigator.vendor||window.opera).substr(0,4)))
}

jQuery.noConflict();
jQuery(document).ready(function(){
    if(isMobile()) alert("Mobile"); else alert("Not Mobile");
});

.substr(0,4)返回前4个字母。如何检测“ android。+ mobile”?
raacer

1
@raacer答案中实际上有两个正则表达式(都在同一行上)-第一个正则表达式检查整个UA字符串,并查找android,mobile等,而第二个正则表达式仅检查UA的前四个字符。
JackW

1
//true / false
function isMobile()
{
   return (/Android|webOS|iPhone|iPad|iPod|BlackBerry/i.test(navigator.userAgent) ); 
}

您也可以按照本教程来检测特定的手机。请点击这里


请添加Mobile到您的RX
oriadam '16

1

使用“ window.screen.width”怎么办?

if (window.screen.width < 800) {
// do something
}

要么

if($(window).width() < 800) {
//do something
}

我猜这是最好的方法,因为每天都有新的移动设备!

(尽管我认为旧浏览器不支持该功能,但是请尝试一下:))


1
什么是景观?
Erick Voodoo

1
这对于某些情况不是很有用。如果调整了桌面浏览器的大小,则可能会错误地将其检测为移动浏览器
toing_toing

PC的可用性和可怕的答案与移动设备本质上是不同的!!
Heitor

1

请注意,大多数新一代移动设备现在的分辨率都超过600x400。即iPhone 6 ...

测试证明:在此处运行最新,最新的文章,并运行一次可选检查,如下所示:

(function(a){
    window.isMobile = (/(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)))
})(navigator.userAgent||navigator.vendor||window.opera);

alert("This browser was found to be a % browser.", window.isMobile ? 'mobile' : 'desktop');

不知何故,以下浏览器应用程序返回了以下结果。规格:iPhone 6S,iOS 10.3.1。

Safari(最新):检测为移动设备。

Chrome(最新):未将其检测为移动设备。

因此,我随后测试了Lantihttps://stackoverflow.com/a/31864119/7183483)的建议,并确实返回了正确的结果(适用于所有iOS设备的移动设备和适用于我的Mac的台式机)。因此,我继续对其进行了一些编辑,因为它将触发两次(针对移动设备和平板电脑)。然后我在iPad上进行测试时注意到,它也作为移动设备返回,这很有意义,因为Lanti的参数使用检查操作系统比什么都重要。因此,我只是将Tablet IF语句移到了移动支票中,如果Tablet支票为负数,则返回mobile,否则返回Tablet。然后,我添加了else子句,以使移动支票可以作为台式机/笔记本电脑返回,因为两者均符合条件,但是随后注意到浏览器检测到CPU和OS品牌。所以我添加了返回的内容,作为if语句其他部分的一部分。为此,我添加了一条警惕的else声明,以防万一。请参见下面,它将很快在Windows 10 PC上进行测试更新。

哦,我还添加了一个'debugMode'变量,以便在调试和常规编译之间轻松切换。

免责声明:对Lanti表示完全的感谢,并且也没有在Windows Tablets上进行过测试……由于操作系统是纯Windows,因此可能会返回台式机/笔记本电脑。一旦找到使用它的朋友,便会检查。

function userAgentDetect() {
    let debugMode = true;
    if(window.navigator.userAgent.match(/Mobile/i)
        || window.navigator.userAgent.match(/iPhone/i)
        || window.navigator.userAgent.match(/iPod/i)
        || window.navigator.userAgent.match(/IEMobile/i)
        || window.navigator.userAgent.match(/Windows Phone/i)
        || window.navigator.userAgent.match(/Android/i)
        || window.navigator.userAgent.match(/BlackBerry/i)
        || window.navigator.userAgent.match(/webOS/i)) {
        if (window.navigator.userAgent.match(/Tablet/i)
            || window.navigator.userAgent.match(/iPad/i)
            || window.navigator.userAgent.match(/Nexus 7/i)
            || window.navigator.userAgent.match(/Nexus 10/i)
            || window.navigator.userAgent.match(/KFAPWI/i)) {
            window.deviceTypeVar = 'tablet';
            if (debugMode === true) {
                alert('Device is a tablet - ' + navigator.userAgent);
            }
        } else {
            if (debugMode === true) {
                alert('Device is a smartphone - ' + navigator.userAgent);
            };
            window.deviceTypeVar = 'smartphone';
        }
    } else if (window.navigator.userAgent.match(/Intel Mac/i)) {
        if (debugMode === true) {
            alert('Device is a desktop or laptop- ' + navigator.userAgent);
        }
        window.deviceTypeVar = 'desktop_or_laptop';
    } else if (window.navigator.userAgent.match(/Nexus 7/i)
        || window.navigator.userAgent.match(/Nexus 10/i)
        || window.navigator.userAgent.match(/KFAPWI/i)) {
        window.deviceTypeVar = 'tablet';
        if (debugMode === true) {
            alert('Device is a tablet - ' + navigator.userAgent);
        }
    } else {
        if (debugMode === true) {
            alert('Device is unknown- ' + navigator.userAgent);
        }
        window.deviceTypeVar = 'Unknown';
    }
}

1

这只是我在项目中使用的已接受答案的es6端口。请注意,这也包括平板电脑。

export const isMobile = () => {
  const vendor = navigator.userAgent || navigator.vendor || window.opera;

  return !!(
    /(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(
      vendor
    ) ||
    /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(
      vendor.substr(0, 4)
    )
  );
};

1

return 'ontouchstart' in window && window.screen.availWidth < 768

怎么样,它扩展了上面的答案但还检查了屏幕尺寸


1

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

/* eslint-disable */
export const IS_MOBILE = (function (a) {
  return (
    /(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)
      )
  )
  // @ts-ignore
})(navigator.userAgent || navigator.vendor || window.opera)
/* eslint-enable */

0

这也可能是一个解决方案。

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;

  console.log('Mobile device:'+isMobile);

  var doc_h = $(document).height(); // returns height of HTML document
  var doc_w = $(document).width(); // returns width of HTML document
  console.log('Height: '+doc_h);
  console.log('width: '+doc_w);

  var iPadVertical = window.matchMedia("(width: 768px) and (height: 1024px) and (orientation: portrait)");
  var iPadHoricontal = window.matchMedia("(width: 1024px) and (height: 767px) and (orientation: landscape)");

  console.log('Height: '+doc_h);
  console.log('width: '+doc_w);

  if (iPadVertical.matches) {
      console.log('Ipad vertical detected');
  }else if (iPadHoricontal.matches){
      console.log('Ipad horicontal detected');
  }else {
      console.log('No Ipad');
  }

如果同时使用这两种方法,则将获得检测不同设备的理想方法。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.