最简判断是用正则 /Mobi|Android|iPhone|iPod|Opera Mini|IEMobile/i.test(navigator.userAgent) 检测移动端,兼容所有现代浏览器;需区分 iPad 时补充 /iPad/i.test(navigator.userAgent) && !/Macintosh.*Safari/i.test(navigator.userAgent),避免误判 macOS Safari。
navigator.userAgent 做最简判断直接读取 navigator.userAgent 字符串,检查是否包含常见移动端关键词。这是兼容性最好、零依赖的方案,适用于所有现代浏览器(包括微信内置浏览器)。
注意:不能只看 "Mobile",因为部分 iPad UA 不含该字段;也不能只看 "iPad",因为 iOS 13+ 的桌面模式会主动隐藏它。
/Mobi|Android|iPhone|iPod|Opera Mini|IEMobile/i.test(navigator.userAgent) —— 覆盖绝大多数手机|| /iPad/i.test(navigator.userAgent) && !/Macintosh.*Safari/i.test(navigator.userAgent)(避免误判 macOS Safari)indexOf("Android") !== -1 这类写法,大小写不安全,正则更稳matchMedia 判断视口宽度更可靠UA 可被伪造或修改,而 window.matchMedia 基于真实设备能力,适合做响应式降级逻辑(比如在 PC 端强制加载桌面版地图组件)。
关键点:它不等于“屏幕物理尺寸”,而是当前 viewport 的有效宽度(受缩放、横竖屏影响)。
立即学习“前端免费学习笔记(深入)”;
matchMedia("(max-width: 768px)").matches 是常用阈值,但不是绝对标准——有些折叠屏展开后也满足该条件matchMedia("(max-width: 768px)").matches && navigator.maxTouchPoints > 1,兼顾尺寸与触控能力mediaQuery.addListener(handler),注意旧版 Safari 需用 addRule 兼容如果 index.html 是由后端渲染(如 PHP/Nginx),可在 HTTP 请求头中解析 User-Agent,直接输出不同 HTML 或 class。这样首屏无需 JS 就能适配。
问题在于:CDN 缓存、爬虫 UA、微信/QQ 内置浏览器 UA 标识混乱,容易误判。
if ($http_user_agent ~* "(Mobi|Android|iPhone)") { set $is_mobile "1"; },再通过 try_files 分流sinergi/browser-detector),自己正则匹配易漏 Edge Mobile、Samsung Browser 等变体它们 UA 字符串里同时含 "MicroMessenger" 和 "Mobile",但部分安卓微信版本会把 UA 改成桌面格式(伪装成 Chrome),导致前端 UA 判断失效。
此时 matchMedia + 'ontouchstart' in window 组合更准,但要注意:Chrome 桌面版开启开发者工具模拟移动设备时,ontouchstart 也会存在。
!!navigator.userAgent.match(/MicroMessenger/i) || !!navigator.userAgent.match(/QQ/d+/i)
screen.width < 900 && 'ontouchstart' in window,排除桌面模拟场景getNetworkType 不能用于设备判断,它返回的是网络类型实际项目里,多数情况用 navigator.userAgent + matchMedia 双保险就够了。真正难处理的是那些 UA 被刻意抹除或篡改的环境,比如某些企业微信定制版、鸿蒙 WebView 的早期版本——这时候得靠用户手动切换按钮兜底。