跳转到内容

能力 · API

Generic Sensor API

发布于 更新于

有限可用不支持的浏览器: Firefox (Desktop)、Firefox (Android)、Safari (macOS)、Safari (iOS)W3C 草案

Generic Sensor API 是一个 Sensor 基接口(start()、stop(),以及 reading、activate、error 事件),由具体的设备传感器继承:Accelerometer、LinearAccelerationSensor、GravitySensor、Gyroscope、AbsoluteOrientationSensor、RelativeOrientationSensor、Magnetometer 和 AmbientLightSensor。页面构造某个具体类,调用 start(),然后在 reading 处理函数中从属性读取最新采样;读数只会投递给安全上下文中可见且获得焦点的文档。

支持情况是仅 Chromium 一家,内部还分两档。Chrome 67(Edge 79、Samsung Internet 9.0、Android WebView 67)无需标志即提供 Accelerometer、LinearAccelerationSensor、Gyroscope、AbsoluteOrientationSensor 与 RelativeOrientationSensor,Chrome 91 加入 GravitySensor。Magnetometer 与 AmbientLightSensor 自 Chrome 56 起存在,但只在 chrome://flags/#enable-experimental-web-platform-features 之后。Firefox 与 Safari 没有实现其中任何一个接口(BCD api.Accelerometer、api.Magnetometer、api.AmbientLightSensor);跨内核获取运动数据的回退路径是 DeviceMotionEvent。

new Accelerometer()
new Accelerometer(options)
new Gyroscope(options)
new AbsoluteOrientationSensor(options)
new Magnetometer(options)
new AmbientLightSensor(options)
sensor.start()
sensor.stop()

构造函数是同步的,返回一个处于 idle 状态的传感器。start() 与 stop() 返回 undefined;激活异步完成,以 activate 事件通知,之后 activated 为 true,第一份采样到达时 hasReading 变为 true,timestamp 携带该采样的 DOMHighResTimeStamp。运动类传感器暴露 x、y、z(加速度计为 m/s²,Gyroscope 为 rad/s,Magnetometer 为 µT);方向类传感器暴露 quaternion 与 populateMatrix(target);AmbientLightSensor 暴露以 lux 计的 illuminance。所有接口都带 [SecureContext]。

每个构造函数接受一个可选的 options 字典。基类 SensorOptions 只有一个成员;运动与方向类传感器在其上扩展了 referenceFrame。

成员 类型 必填 适用于 说明
frequency double(Hz) 否 所有传感器 期望的采样与上报频率。规范把它定为提示:浏览器可以把它钳制到平台传感器的范围内。Chromium 把加速度计、陀螺仪和方向传感器的上限定为 60 Hz(默认 10 Hz),Magnetometer 与 AmbientLightSensor 上限为 10 Hz(sensor_traits.h)。
referenceFrame "device" 或 "screen" 否,默认 "device" Accelerometer、LinearAccelerationSensor、GravitySensor、Gyroscope、Magnetometer、两种方向传感器 读数所用的坐标系。"screen" 让坐标轴随当前屏幕方向旋转,横放的平板仍把“上”报告为 y 轴正方向。

读数在抵达页面前已被量化:Accelerometer 规范把 x、y、z 四舍五入到最接近的 0.1 m/s²,这是一项反指纹措施,也决定了你能检测到的最小运动幅度。

构造函数同步抛出;start() 从不抛出,而是通过 error 事件报告失败,event.error 即下表中的 DOMException。

异常 位置 条件
SecurityError 构造函数 文档不被允许使用该传感器的 policy-controlled feature(accelerometer、gyroscope、magnetometer 或 ambient-light-sensor;方向传感器需要 accelerometer 加 gyroscope,绝对方向传感器还需要 magnetometer)。跨源 iframe 需要在 allow 属性中列出它们。
NotSupportedError 构造函数 options 含有该传感器类型不支持的键(「initialize a sensor object」步骤)。
NotAllowedError error 事件 传感器权限请求的结果为 "denied"。Chromium 把这些权限对应到 navigator.permissions.query() 中的 accelerometer、gyroscope、magnetometer、ambient-light-sensor 名称。
NotReadableError error 事件 「connect to sensor」失败:设备没有这种传感器、平台拒绝提供,或传感器在使用中停止。传感器回到 "idle" 并保持沉默,直到再次调用 start()。

new Magnetometer() 抛出的 ReferenceError 不是传感器错误,它表示当前浏览器没有定义这个构造函数,这是该做特性检测而不是 catch 的情形。

示例精确检测所需的构造函数,缺失时回退到 Firefox 与 Safari 都实现的 DeviceMotionEvent,两条路径都没有时退回静态 UI。

用 Accelerometer 检测摇一摇,并以 DeviceMotionEvent 回退

Section titled “用 Accelerometer 检测摇一摇,并以 DeviceMotionEvent 回退”

优先走加速度计路径,因为它按你选择的频率投递经过校准和量化的采样。构造函数缺失时,同一套阈值跑在 devicemotion 上,它报告的是未量化的 accelerationIncludingGravity。

const SHAKE_THRESHOLD = 25; // m/s^2,合成幅值
function onShake(callback) {
if ('Accelerometer' in window) {
let sensor;
try {
sensor = new Accelerometer({ frequency: 30 });
} catch (err) {
console.warn(`${err.name}: ${err.message}`); // 被 Permissions Policy 拦下
return false;
}
sensor.addEventListener('error', (event) => {
console.warn(`${event.error.name}: ${event.error.message}`);
});
sensor.addEventListener('reading', () => {
if (Math.hypot(sensor.x, sensor.y, sensor.z) > SHAKE_THRESHOLD) callback();
});
sensor.start();
return true;
}
if ('DeviceMotionEvent' in window) {
window.addEventListener('devicemotion', (event) => {
const a = event.accelerationIncludingGravity;
if (a && Math.hypot(a.x, a.y, a.z) > SHAKE_THRESHOLD) callback();
});
return true;
}
return false; // 没有运动数据:改为显示一个按钮
}
if (!onShake(() => document.body.classList.toggle('shaken'))) {
document.querySelector('#shake-button').hidden = false;
}

iOS 13 及之后的 devicemotion 本身也受 DeviceMotionEvent.requestPermission() 门控,且必须在用户手势中调用;真实应用里这段回退分支应放在一次点击之后。

AbsoluteOrientationSensor 同时依赖三项权限。先查询它们,页面就能说明哪一项被拦,而不是等 error 事件里的 NotAllowedError。

async function startCompass(onHeading) {
if (!('AbsoluteOrientationSensor' in window)) return 'unsupported';
const names = ['accelerometer', 'gyroscope', 'magnetometer'];
const states = await Promise.all(
names.map((name) => navigator.permissions.query({ name }).then((s) => s.state)),
);
if (states.includes('denied')) return 'denied';
const sensor = new AbsoluteOrientationSensor({ frequency: 10, referenceFrame: 'screen' });
sensor.addEventListener('reading', () => {
const [qx, qy, qz, qw] = sensor.quaternion;
const yaw = Math.atan2(2 * (qw * qz + qx * qy), 1 - 2 * (qy * qy + qz * qz));
onHeading(((yaw * 180) / Math.PI + 360) % 360);
});
sensor.addEventListener('error', (event) => {
if (event.error.name === 'NotReadableError') onHeading(null); // 此设备没有磁力计
});
sensor.start();
return 'started';
}

返回字符串让调用方渲染三种状态:指南针、“请开启运动访问权限”的提示,或 API 不存在时正北朝上的普通地图。

规范

规范状态
Generic Sensor API(通用传感器)W3C 草案
Generic Sensor API: the Sensor interfaceW3C
Accelerometer: the Accelerometer interfaceW3C
Gyroscope: the Gyroscope interfaceW3C
Orientation Sensor: the AbsoluteOrientationSensor interfaceW3C
  • 图例
  • 支持
  • 部分支持
  • 需开启标志
  • 不支持
  • 未知
浏览器 / 平台支持版本置信度来源备注
Chrome (Desktop)支持67高来源—
Chrome (Android)支持67高来源1
Edge (Desktop)支持79高来源2
Firefox (Desktop)不支持—高来源3
Firefox (Android)不支持—高来源45
Safari (macOS)不支持—高来源6
Safari (iOS)不支持—高来源78
Samsung Internet支持9.0高来源9
WebView (Android)支持67高来源10
  1. 由 browser-compat-data 镜像自 Chrome 的数据推导。
  2. 由 browser-compat-data 镜像自 Chrome 的数据推导。
  3. browser-compat-data 未记录 Firefox 的支持。
  4. browser-compat-data 未记录 Firefox for Android 的支持。
  5. 由 browser-compat-data 镜像自 Firefox 的数据推导。
  6. browser-compat-data 未记录 Safari 的支持。
  7. browser-compat-data 未记录 iOS 版 Safari 的支持。
  8. 由 browser-compat-data 镜像自 Safari 的数据推导。
  9. 由 browser-compat-data 镜像自 Chrome Android 的数据推导。
  10. 由 browser-compat-data 镜像自 Chrome Android 的数据推导。

源数据: /compatibility/sensors.json · 全球使用占比: 72 % (StatCounter 2026-05)

来源: 规范 · MDN · 最近核验 2026-10-03 · 置信度: 高 (由来源计算)