screen orientation api 在 safari(含 ios)完全不支持,chrome 58+、edge 79+、firefox 63+ 支持 lock(),但需在用户手势中调用且参数必须为 'portrait' 或 'landscape' 等枚举值,ios 需原生层实现,css 无法替代锁定。

Screen Orientation API 不支持所有浏览器,先查兼容性再写逻辑
Chrome 58+、Edge 79+、Firefox 63+ 支持 screen.orientation.lock(),但 Safari(包括 iOS)**完全不支持**该 API。这意味着你在 iPhone 或 iPad 上调用 screen.orientation.lock('landscape') 会直接抛出 TypeError: screen.orientation.lock is not a function 错误,且无法降级处理——它根本不存在。
常见错误现象:本地开发用 Chrome 测试正常,上线后 iOS 用户反馈“横屏没反应”或白屏崩溃;或者用 try/catch 包裹却没意识到 lock 方法压根未定义,catch 根本捕获不到。
- 务必在调用前检测:
if ('orientation' in screen && typeof screen.orientation.lock === 'function') - iOS 必须靠原生层(如 Cordova/ Capacitor 插件)或 WKWebView 配置实现方向锁定,Web 层无解
- Android WebView 中,需确认 Webview 启用了
setRequestedOrientation(原生侧控制),否则 JS 调用仍无效
lock() 只在用户手势触发的上下文中有效
screen.orientation.lock() 是受权限限制的异步操作,只能在用户主动交互(如 click、touchend)的事件回调中调用,不能放在 setTimeout、DOMContentLoaded 或自动轮播逻辑里。
典型失败场景:页面加载完自动锁横屏,结果 Promise 永远 pending 或直接 reject;或者在 onload 里调用,控制台报 DOMException: The operation is insecure.
- 正确做法:绑定到按钮点击,例如:
document.getElementById('lockBtn').addEventListener('click', () => screen.orientation.lock('landscape')) - 注意:部分 Android 厂商定制系统(如华为 EMUI)即使满足手势条件,也可能静默拒绝,需 fallback 提示用户手动旋转
- 锁屏后若用户强制旋转,部分安卓机型不会触发
orientationchange事件,别依赖它做 UI 同步
可用方向值只有 'portrait'、'landscape'、'portrait-primary' 等有限字符串
screen.orientation.lock() 接收的参数不是任意字符串,而是严格枚举值。传入 'horizontal'、'vertical' 或空字符串会导致立即 reject,并抛出 TypeError: Failed to execute 'lock' on 'ScreenOrientation': Invalid orientation。
不同平台对方向的理解也有差异:比如 'landscape' 表示“任一横屏”,而 'landscape-primary' 特指系统默认横屏(通常为 home 键在右),部分设备可能不支持后者。
- 推荐优先使用
'portrait'和'landscape'—— 兼容性最好 - 避免用
'natural':它依赖设备硬件方向传感器,很多安卓机返回undefined,且无法作为 lock 参数 - 解锁用
screen.orientation.unlock(),无需参数;不要试图传null或空串
CSS media query 无法替代 JS 锁定,但可辅助响应式降级
有人试图用 @media (orientation: landscape) 强制隐藏竖屏元素来“模拟”锁定,这是无效的。CSS 只能响应当前方向,不能阻止用户旋转屏幕,也无法触发系统级方向干预。
但它可以配合 JS 使用:当 screen.orientation.lock() 不可用时,用媒体查询 + 提示文案引导用户(比如“请将手机横过来使用”),并监听 resize 或 orientationchange 动态调整布局。
- 注意:iOS 的
orientationchange事件基本不可靠,建议改用window.matchMedia('(orientation: landscape)')监听 - Android 上
resize触发频繁,加防抖(如 200ms)避免重复计算 - 不要在 CSS 里写
transform: rotate(90deg)伪装横屏——输入框失焦、滚动异常、Canvas 渲染错位问题频发
console.warn 比强行 try/catch 更诚实。前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











