不能——iOS Safari 必须通过用户可信手势(如 touchstart)调用 DeviceMotionEvent.requestPermission() 后才能监听 devicemotion,且 WKWebView 中需原生配合,摇一摇检测需基于 accelerationIncludingGravity 的向量模长变化率双阈值判定。
不能——除非用户完成一次「可信的用户手势」(如点击、触摸、键盘输入)。这是 iOS 13+ 的硬性限制,不是 bug,是 Safari 的安全策略。直接在 window.onload 或 setTimeout 里监听 deviceorientation 或 devicemotion,iOS 会静默拒绝启用传感器,event.acceleration.x 等字段始终为 null。
只有在用户主动触发的事件回调中,才能首次调用 DeviceMotionEvent.requestPermission()(iOS 13+)或直接开始监听(iOS 12 及更早需手动唤醒)。否则摇一摇永远没响应。
button、div 等可点击元素的 onclick 或 ontouchstart 上(推荐后者,避免点击延迟)document.getElementById('shake-btn').ontouchstart = async () => {
try {
await DeviceMotionEvent.requestPermission();
window.addEventListener('devicemotion', handleShake);
} catch (e) {
console.warn('Permission denied:', e);
}
};别依赖单次加速度峰值——iOS 设备休眠时传感器数据抖动大,且不同机型 baseline 不同。应计算加速度向量模长变化率,并设双阈值过滤噪声。
event.accelerationIncludingGravity(非 acceleration),它包含重力分量,更稳定const acc = Math.sqrt(x*x + y*y + z*z)
acc > 25(单位 m/s²)且与前一稳定值差值 > 12 时才判定为有效摇动WKWebView 默认禁用传感器 API,即使网页里写了 requestPermission 也会抛 SecurityError。必须由原生层显

立即学习“前端免费学习笔记(深入)”;
WKWebViewConfiguration 中设置 mediaTypesRequiringUserActionForPlayback = [] 不够,还需 configuration.preferences.setValue(true, forKey: "allowAirPlayForMediaPlayback") ——但这不解决传感器问题WKScriptMessageHandler,当 JS 触发「准备摇一摇」时,OC/Swift 调用 [self.webView evaluateJavaScript:@"..." completionHandler:nil] 并提前配置好 configuration.usesWebProcessPool = NO(不推荐)或改用 SFSafariViewController
CMMotionManager 检测,JS 通过 webkit.messageHandlers.xxx.postMessage() 接收事件
来电咨询