navigator.userAgent

最简单的方法就是分析浏览器的 user agent 字符串,它包含了设备信息。通过判断是否包含Mobile、Android、iPhone等关键字,就可以认定是移动设备。

if (/iPhone|iPod|Android|ios|iPad|BlackBerry|Mobile/i.test(navigator.userAgent)) {
  // 当前设备是移动设备
}

// 另一种写法
if (
  navigator.userAgent.match(/Mobile/i) ||
  navigator.userAgent.match(/Android/i) ||
  navigator.userAgent.match(/iPhone/i)
) {
  // 当前设备是移动设备
}

Android 或 iOS

let browser = {
    versions: function() {
        var ua = navigator.userAgent;
        return {//移动终端浏览器版本信息 
            trident: ua.indexOf('Trident') > -1, //IE内核
            presto: ua.indexOf('Presto') > -1, //opera内核
            webKit: ua.indexOf('AppleWebKit') > -1, //苹果、谷歌内核
            gecko: ua.indexOf('Gecko') > -1 && ua.indexOf('KHTML') == -1, //火狐内核
            mobile: !!ua.match(/AppleWebKit.*Mobile.*/) || !!ua.match(/AppleWebKit/), //是否为移动终端
            ios: !!ua.match(/\(i[^;]+;( U;)? CPUa.+Mac OS X/), //ios终端
            android: ua.indexOf('Android') > -1 || ua.indexOf('Linux') > -1, //android终端或者uc浏览器
            iPhone: ua.indexOf('iPhone') > -1 || ua.indexOf('Mac') > -1, //是否为iPhone或者QQHD浏览器
            iPad: ua.indexOf('iPad') > -1, //是否iPad
            webApp: ua.indexOf('Safari') == -1, //是否web应该程序,没有头部与底部
            winPhone: ua.indexOf('Windows Phone') > -1 //是否为Windows Phone
        };
    }(),
    language: (navigator.browserLanguage || navigator.language).toLowerCase()
}
 
if (browser.versions.ios || browser.versions.iPhone || browser.versions.iPad) {
    window.location="https://itunes.apple.com/xxx";
}
else if (browser.versions.android) {
    window.location="http://xxx/xxx.apk";
}

// console.log("语言版本: " + browser.language);
// console.log(" 是否为移动终端: " + browser.versions.mobile);
// console.log(" ios终端: " + browser.versions.ios);
// console.log(" android终端: " + browser.versions.android);
// console.log(" 是否为iPhone: " + browser.versions.iPhone);
// console.log(" 是否iPad: " + browser.versions.iPad);

window.orientation

侦测屏幕方向,判断横屏或竖屏
window.orientation属性用于获取屏幕的当前方向,只有移动设备才有这个属性,桌面设备会返回undefined。

function orient() {
    if (window.orientation == 0 || window.orientation == 180) {
        $("body").attr("class", "portrait");
        orientation = 'portrait';
        return false;
    }
    else if (window.orientation == 90 || window.orientation == -90) {
        $("body").attr("class", "landscape");
        orientation = 'landscape';
 
        return false;
    }
}

缺点:iOS15 中 Safari 才支持该属性;

window.screen,window.innerWidth

window.screen 对象返回用户设备的屏幕信息,该对象的width属性是屏幕宽度(单位为像素)。

const getBrowserWidth = function() {
  if (window.innerWidth < 768) {
    return "xs";
  } else if (window.innerWidth < 991) {
    return "sm";
  } else if (window.innerWidth < 1199) {
    return "md";
  } else {
    return "lg";
  }
};

touch 事件

手机浏览器的 DOM 元素可以通过ontouchstart属性,为touch事件指定监听函数。

if ("ontouchstart" in window) {
	startEvt = "touchstart";
	moveEvt = "touchmove";
	endEvt = "touchend";
} else {
	startEvt = "mousedown";
	moveEvt = "mousemove";
	endEvt = "mouseup";
}

window.matchMedia()

matchMedia() 返回一个新的 MediaQueryList 对象,表示指定的媒体查询字符串解析后的结果。
matchMedia()方法的值可以是任何一个 CSS @media 规则 的特性, 如 min-height, min-width, orientation 等。
window.matchMedia() 方法接受一个 CSS 的 media query 语句作为参数,判断这个语句是否生效。

MediaQueryList 对象有以下两个属性:

  • media:查询语句的内容。
  • matches:用于检测查询结果,如果文档匹配 media query 列表,值为 true,否则为 false。
window.matchMedia("only screen and (max-width: 760px)").matches;

上例中window.matchMedia()的参数是一个 CSS 查询语句,表示只对屏幕宽度不超过 700 像素的设备生效。它返回一个对象,该对象的matches属性是一个布尔值。如果是true,就表示查询生效,当前浏览器匹配此条件。

除了通过屏幕宽度判断,还可以通过指针的精确性判断。

window.matchMedia("(pointer:coarse)").matches;
window.matchMedia("(any-pointer:coarse)").matches;

CSS 语句pointer:coarse表示当前设备的指针是不精确的。由于手机不支持鼠标,只支持触摸,所以符合这个条件。
有些设备支持多种指针,比如同时支持鼠标和触摸。pointer:coarse只用来判断主指针,此外还有一个any-pointer命令判断所有指针。

MediaQueryList 对象还可以监听事件。通过监听,在查询结果发生变化时,就调用指定的回调函数。

addListener(functionref) 添加一个新的监听器函数,该函数在媒体查询的结果发生变化时执行。
removeListener(functionref) 从媒体查询列表中删除之前添加的监听器。 如果指定的监听器不在列表中,则不执行任何操作。

function myFunction(x) {
    if (x.matches) { // 媒体查询
        document.body.style.backgroundColor = "yellow";
    } else {
        document.body.style.backgroundColor = "pink";
    }
}
 
var x = window.matchMedia("(max-width: 700px)")
myFunction(x) // 执行时调用的监听函数
x.addListener(myFunction) // 状态改变时添加监听器