iOS Safari完全不支持Screen Orientation API,调用screen.orientation.lock()会抛出NotSupportedError或静默失败;仅Android Chrome、Firefox桌面版等支持,且需用户手势触发。
直接说结论:iOS Safari(包括所有基于 WebKit 的 iOS 浏览器)完全不支持 screen.orientation.lock(),调用会抛出 NotSupportedError 或静默失败。这不是配置问题,是苹果明确拒绝实现该 API。如果你的目标用户包含 iPhone/iPad 用户,任何依赖此 API 的“横屏锁定”逻辑都会失效。
常见错误现象:screen.orientation.lock('landscape') 在 iOS 上返回 Promise rejected,或根本无响应;screen.orientation.type 始终为 "portrait-primary",即使设备已物理旋转。
screen.orientation.lock() 是受权限约束的异步操作,必须在用户点击、触摸、键盘事件等“可信任事件”回调中调用,否则会立即 reject 并报错 SecurityError: The operation is insecure。
典型错误写法:onload、setTimeout、或组件挂载后自动调用 —— 这些都不算用户手势上下文。
立即学习“前端免费学习笔记(深入)”;
onclick 或 ontouchstart,例如:<button onclick="lockLandscape()">进入横屏模式</button><script>function lockLandscape() { screen.orientation.lock('landscape').catch(e => console.error(e));}</script>
unlock() 再重新 lock既然原生 API 在 iOS 上走不通,务实做法是放弃“系统级锁定”,转而用视觉和交互模拟横屏感:旋转容器、禁用滚动、适配触控区域。
核心思路是监听 window.orientation(已废弃但 iOS 仍可用)或 matchMedia('(orientation: landscape)'),再用 CSS transform: rotate(90deg) 配合 viewport 动态缩放。
.landscape-simulated { transform: rotate(90deg); transform-origin: left top; width: 100vh; height: 100vw; position: absolute; top: 0; left: 0;}
matchMedia('(orientation: landscape)') 监听方向变化,而非依赖 screen.orientation
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no">,否则旋转后缩放失控不要只靠 'orientation' in screen 判断,因为 iOS 也暴露 screen.orientation 对象(只是方法不可用)。真实可用性必须通过 try/catch + 实际调用验证。
推荐检测函数:
async function canLockOrientation() { if (!screen.orientation || !screen.orientation.lock) return false; try { await screen.orientation.lock('portrait'); await screen.orientation.unlock(); return true; } catch (e) { return false; }}
这个函数会在 Android 上 resolve true,在 iOS 上 resolve false,且不污染当前 orientation 状态。
容易忽略的一点:某些安卓 WebView(如微信内置浏览器)虽然有 lock 方法,但实际调用会静默失败 —— 所以运行时检测比 UA 判断可靠得多。