navigator.vibrate()需用户手势触发,否则报SecurityError或返回false;参数须为数字或数字数组,iOS仅支持≤15ms单次震动且需手动开启触感反馈。
navigator.vibrate()会报错?不会触发震动,大概率是因为当前上下文不满足“用户手势激活”要求——navigator.vibrate() 必须在用户点击、触摸等事件回调中首次调用,且不能在页面加载完成时自动执行。Chrome 和 Safari(iOS 16.4+)都强制此限制,否则返回 false 或抛出 SecurityError。
实操建议:
button 的 click 或 touchstart 事件里,不要放在 DOMContentLoaded 或 setTimeout 中[10]、[15] 等),不支持长序列或重复模式navigator.vibrate() 参数怎么传才有效?参数必须是数字或数字数组,其他类型(如字符串 "200"、对象、null)会被静默忽略,返回 true 但无实际震动。
常见有效写法:
立即学习“前端免费学习笔记(深入)”;
navigator.vibrate(200):震动 200ms(单次)navigator.vibrate([100, 50, 200]):震 100ms → 停 50ms → 震 200ms(iOS 不支持停顿,会合并为连续震动)navigator.vibrate(0) 或 navigator.vibrate([]):清空正在执行的震动队列(相当于取消)注意:[0, 100] 这类以 0 开头的数组,在部分 Android 版本上可能被截断,建议避免。
iOS 对 Vibration API 支持极有限:仅 iOS 16.4+ 开放,且默认关闭;即使启用,也只允许短脉冲(≤ 15ms 单次,或 ≤ 400ms 总时长),且不支持振动序列中的停顿间隔。
兼容性对策:
if ("vibrate" in navigator),再判断平台:/iPad|iPhone|iPod/.test(navigator.userAgent)
navigator.vibrate(15),别传数组典型原因是多次快速调用 vibrate() 而未清队列,尤其在按钮连点或动画循环中。Android 会排队执行,iOS 则可能丢弃或异常延长。
安全做法:
navigator.vibrate(0)
setTimeout 或 requestAnimationFrame 控制最小间隔(如 ≥ 300ms)scroll、input 等高频事件中直接调用真机测试比模拟器可靠得多——很多浏览器 DevTools 的传感器模拟不触发真实震动,也测不出 iOS 的权限拦截逻辑。