screen.colorDepth 和screen.pixelDepth 返回一样的值,即显示器每像素颜色的位深。根据
CSS 对象模型(CSSOM)规范:
screen.colorDepth 和screen.pixelDepth 属性应该返回输出设备中每像素用于显示
颜色的位数,不包含alpha 通道。
Chrome 中这两个属性的值如下所示:
console.log(screen.colorDepth); // 24
console.log(screen.pixelDepth); // 24
screen.orientation
screen.orientation 属性返回一个ScreenOrientation 对象,其中包含Screen Orientation API
定义的屏幕信息。这里面最有意思的属性是angle 和type,前者返回相对于默认状态下屏幕的角度,
后者返回以下4 种枚举值之一:
portrait-primary
portrait-secondary
landscape-primary
landscape-secondary
例如,在Chrome 移动版中,screen.orientation 返回的信息如下:
// 垂直看
console.log(screen.orientation.type); // portrait-primary
console.log(screen.orientation.angle); // 0
// 向左转
console.log(screen.orientation.type); // landscape-primary
console.log(screen.orientation.angle); // 90
// 向右转
console.log(screen.orientation.type); // landscape-secondary
console.log(screen.orientation.angle); // 270
根据规范,这些值的初始化取决于浏览器和设备状态。因此,不能假设portrait-primary 和0
始终是初始值。这两个值主要用于确定设备旋转后浏览器的朝向变化。
浏览器元数据
navigator 对象暴露出一些API,可以提供浏览器和操作系统的状态信息。
- Geolocation API
navigator.geolocation 属性暴露了Geolocation API,可以让浏览器脚本感知当前设备的地理位
置。这个API 只在安全执行环境(通过HTTPS 获取的脚本)中可用。
这个API 可以查询宿主系统并尽可能精确地返回设备的位置信息。根据宿主系统的硬件和配置,返回结果的精度可能不一样。手机GPS 的坐标系统可能具有极高的精度,而IP 地址的精度就要差很多。
根据Geolocation API 规范:
地理位置信息的主要来源是GPS 和IP 地址、射频识别(RFID)、Wi-Fi 及蓝牙Mac 地址、
GSM/CDMA 蜂窝ID 以及用户输入等信息。
要获取浏览器当前的位置, 可以使用getCurrentPosition() 方法。这个方法返回一个
Coordinates 对象,其中包含的信息不一定完全依赖宿主系统的能力:
// getCurrentPosition()会以position 对象为参数调用传入的回调函数
navigator.geolocation.getCurrentPosition((position) => p = position);
这个position 对象中有一个表示查询时间的时间戳,以及包含坐标信息的Coordinates 对象:
console.log(p.timestamp); // 1525364883361
console.log(p.coords); // Coordinates {…}
Coordinates 对象中包含标准格式的经度和纬度,以及以米为单位的精度。精度同样以确定设备
位置的机制来判定。
console.log(p.coords.latitude, p.coords.longitude); // 37.4854409, -122.2325506
console.log(p.coords.accuracy); // 58
Coordinates 对象包含一个altitude(海拔高度)属性,是相对于1984 世界大地坐标系(World
Geodetic System,1984)地球表面的以米为单位的距离。此外也有一个altitudeAccuracy 属性,这
个精度值单位也是米。为了取得Coordinates 中包含的这些信息,当前设备必须具备相应的能力(比
如GPS 或高度计)。很多设备因为没有能力测量高度,所以这两个值经常有一个或两个是空的。
console.log(p.coords.altitude); // -8.800000190734863
console.log(p.coords.altitudeAccuracy); // 200
Coordinates 对象包含一个speed 属性,表示设备每秒移动的速度。还有一个heading(朝向)
属性,表示相对于正北方向移动的角度(0 ≤ heading < 360)。为获取这些信息,当前设备必须具备相
应的能力(比如加速计或指南针)。很多设备因为没有能力测量高度,所以这两个值经常有一个是空的,
或者两个都是空的。
获取浏览器地理位置并不能保证成功。因此getCurrentPosition()方法也接收失败回调函数作
为第二个参数,这个函数会收到一个PositionError 对象。在失败的情况下,Positio
nError 对象
中会包含一个code 属性和一个message 属性,后者包含对错误的简短描述。code 属性是一个整数,
表示以下3 种错误。
PERMISSION_DENIED:浏览器未被允许访问设备位置。页面第一次尝试访问Geolocation API
时,浏览器会弹出确认对话框取得用户授权(每个域分别获取)。如果返回了这个错误码,则要
么是用户不同意授权,要么是在不安全的环境下访问了Geolocation API。message 属性还会提
供额外信息。
POSITION_UNAVAILABLE:系统无法返回任何位置信息。这个错误码可能代表各种失败原因,
但相对来说并不常见,因为只要设备能上网,就至少可以根据IP 地址返回一个低精度的坐标。
TIMEOUT:系统不能在超时时间内返回位置信息。关于如何配置超时,会在后面介绍。
// 浏览器会弹出确认对话框请用户允许访问Geolocation API
// 这个例子显示了用户拒绝之后的结果
navigator.geolocation.getCurrentPosition(
() => {},
(e) => {
console.log(e.code); // 1
console.log(e.message); // User denied Geolocation
}
);
// 这个例子展示了在不安全的上下文中执行代码的结果
navigator.geolocation.getCurrentPosition(
() => {},
(e) => {
console.log(e.code); // 1
console.log(e.message); // Only secure origins are allowed
}
);
Geolocation API 位置请求可以使用PositionOptions 对象来配置,作为第三个参数提供。这个对
象支持以下3 个属性。
enableHighAccuracy:布尔值,true 表示返回的值应该尽量精确,默认值为false。默认情
况下,设备通常会选择最快、最省电的方式返回坐标。这通常意味着返回的是不够精确的坐标。
比如,在移动设备上,默认位置查询通常只会采用Wi-Fi 和蜂窝网络的定位信息。而在
enableHighAccuracy 为true 的情况下,则会使用设备的GPS 确定设备位置,并返回这些值
的混合结果。使用GPS 会更耗时、耗电,因此在使用enableHighAccuracy 配置时要仔细权
衡一下。
timeout:毫秒,表示在以TIMEOUT 状态调用错误回调函数之前等待的最长时间。默认值是
0xFFFFFFFF(232 – 1)。0 表示完全跳过系统调用而立即以TIMEOUT 调用错误回调函数。
maximumAge:毫秒,表示返回坐标的最长有效期,默认值为0。因为查询设备位置会消耗资源,
所以系统通常会缓存坐标并在下次返回缓存的值(遵从位置缓存失效策略)。系统会计算缓存期,
如果Geolocation API 请求的配置要求比缓存的结果更新,则系统会重新查询并返回值。0 表示强
制系统忽略缓存的值,每次都重新查询。而Infinity 会阻止系统重新查询,只会返回缓存的
值。JavaScript 可以通过检查Position 对象的timestamp 属性值是否重复来判断返回的是不
是缓存值。