Screen Orientation API 兼容性差:Safari 完全不支持,Chrome/Edge 仅限 HTTPS/PWA/全屏,Firefox 90+ 已移除;需用 'orientation' in screen && screen.orientation 防御检测;监听 screen.orientation.addEventListener('change') 获取方向变化;type 值为四种逻辑字符串,应结合 angle 判断横竖;lock() 需用户手势触发且平台限制多,推荐以 CSS 媒体查询和 resize 监听为主。

Screen Orientation API 不支持所有浏览器,先检查可用性
直接调用 screen.orientation 会报 TypeError: Cannot read property 'orientation' of undefined —— 这是因为 Safari(包括 iOS/iPadOS)完全不支持该 API,Chrome 和 Edge 虽支持但仅限于全屏、安装为 PWA 或 HTTPS 环境下。Firefox 从 90+ 版本起已移除支持(screen.orientation 返回 undefined)。
检测方式必须带防御性判断:
if ('orientation' in screen && screen.orientation) {
console.log('Orientation API available');
} else {
console.log('Fallback needed');
}
- 不要只检查
'orientation' in screen,Safari 会返回true但screen.orientation是undefined - 在 HTTP 页面中,Chrome 会静默禁用该 API,不会抛错但
screen.orientation.type始终为'portrait-primary' - iOS 上唯一可行的替代方案是监听
resize+innerWidth/innerHeight比值变化
监听屏幕方向变化要用 addEventListener,不是轮询
screen.orientation 是一个实时更新的对象,但它的 type 和 angle 属性**不会触发 getter 重计算**,所以不能靠定时读取。正确方式是监听 orientationchange 事件(注意:这不是 window 事件,而是 screen.orientation 实例上的)。
if (screen.orientation && screen.orientation.addEventListener) {
screen.orientation.addEventListener('change', () => {
console.log(screen.orientation.type); // 'landscape-primary', 'portrait-secondary', etc.
});
}
- 事件名是
'change',不是'orientationchange'(后者是旧版非标准事件,已被废弃) - 该事件在设备物理旋转时触发,但不会在 CSS
@media (orientation: landscape)匹配变化时触发 - 部分安卓 WebView(如微信内置浏览器)可能不触发此事件,需配合
resize降级
screen.orientation.type 的取值只有 4 种,别硬套横竖判断
screen.orientation.type 返回的是逻辑方向字符串,不是布尔值或角度数字。它取决于设备自然方向(natural orientation)和当前旋转状态,常见值为:
立即学习“前端免费学习笔记(深入)”;
-
'portrait-primary':设备自然方向为竖屏,且未旋转(如手机正常持握) -
'portrait-secondary':自然方向为竖屏,但上下颠倒(180°) -
'landscape-primary':自然方向为横屏(如某些平板),右侧朝下(90°) -
'landscape-secondary':自然方向为横屏,左侧朝下(270°)
别写 if (type.includes('landscape')) 来判断横屏——有些设备(如 Surface Pro)自然方向是横屏,'portrait-primary' 反而表示横置状态。更稳妥的方式是结合 screen.orientation.angle(返回 0/90/180/270)做判断:
const isLandscape = [90, 270].includes(screen.orientation.angle);
强制锁定方向需用户手势触发,且仅限部分场景
调用 screen.orientation.lock('landscape') 必须由用户手势(如 click、touchend)触发,否则会拒绝并抛出 DOMException: Permission denied。即使满足条件,也受平台限制:
- Android Chrome 支持锁定(但仅对全屏或 PWA 生效)
- 桌面 Chrome 不支持锁定,调用后静默失败
- iOS 完全不支持
lock()方法,会直接报TypeError: screen.orientation.lock is not a function - 锁定后若用户手动旋转,部分安卓机型仍可绕过(系统级限制)
实际使用时务必包裹 try/catch,并准备 UI 提示:
button.addEventListener('click', async () => {
try {
await screen.orientation.lock('landscape');
} catch (err) {
console.warn('Lock failed:', err.name); // 可能是 'NotAllowedError' 或 'NotSupportedError'
}
});
真正稳定可控的方向适配,还是得靠 CSS 媒体查询 + resize 监听组合实现;Screen Orientation API 更像是一个“增强层”,而非基础依赖。



















