应使用 window.matchmedia 监听横竖屏,因其精准、无抖动、兼容性好;window.orientation 和 orientationchange 事件在现代浏览器中已废弃或不可靠,无法同步 css 渲染方向。

直接用 window.matchMedia("(orientation: portrait)") 监听,别碰 window.orientation 或 orientationchange 事件——它们在现代浏览器里要么废弃,要么不触发、不同步、不可靠。
为什么不能用 window.orientation 或 orientationchange
Chrome 99+ 已彻底移除 window.orientation;Safari 和 Firefox 早已标记为 deprecated,且只返回页面加载时的初始值。而 orientationchange 事件在 iOS 12+ 和主流安卓 WebView 中基本不触发,或延迟数秒才发,和 CSS 渲染完全脱节。你改了编辑器高度,但屏幕已转完两圈——用户看到的是错位、滚动条卡死、工具栏被裁切。
window.matchMedia 怎么监听横竖屏并触发编辑器重置
核心是监听媒体查询匹配状态变化,不是轮询宽高比。编辑器(比如 CodeMirror、Monaco、或者自研的 contenteditable 区域)布局重置必须基于视口方向的真实切换,而非像素抖动。
- 用
window.matchMedia("(orientation: landscape)")获取横屏状态,.matches返回true表示当前横屏 - 监听
change事件,回调中执行重置逻辑:比如调整编辑器容器height、切换工具栏位置、重设行号宽度、触发editor.layout() - 首次加载时也得手动调用一次重置函数,避免冷启动时样式错位
- 不要在回调里直接写
editor.setSize(...)—— 如果编辑器尚未初始化完成,会静默失败;先加个if (editor.isReady)或类似守卫
编辑器重置时容易踩的坑
横竖屏切换常伴随软键盘弹出/收起、滚动条出现/消失、甚至 Safari 的 viewport 缩放锁定问题,这些都会干扰编辑器尺寸计算。
-
@media (orientation: landscape)在 CSS 中不生效?检查<meta name="viewport">是否缺失或含user-scalable=no—— 后者会强制禁用旋转,导致媒体查询永远不匹配 - 别用
window.innerWidth > window.innerHeight判断方向:横屏下软键盘弹出会压窄视口,误判为竖屏;matchMedia 基于渲染引擎判定,不受临时 UI 干扰 - Monaco Editor 调用
editor.layout()前,确保其容器已应用新尺寸;可加requestAnimationFrame延迟一帧再调用,避免 DOM 尚未重排就计算 - CodeMirror 6 需要重新 apply
EditorView.theme或更新height插件配置,仅改容器 style 不够
兼容性与兜底处理
IE11 不支持 addEventListener("change"),但 IE11 本身无自动横竖屏逻辑,实际影响极小。若真要保,用 mql.addListener() 替代,注意它不传 MediaQueryListEvent,而是直接传 MediaQueryList 对象,需手动读 .matches。
真正该关注的是 Safari 移动端:某些旧版 WebKit 在 matchMedia 回调中修改 contenteditable 元素的 style.height 可能不立即生效,建议配合 getComputedStyle 检查计算后高度是否更新,必要时触发 editor.refresh() 或强制重绘。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











