最常用且可靠的方式是用 window.innerWidth 和 window.innerHeight 获取视口尺寸,它们返回浏览器可视区域宽高(不含滚动条),响应式强、实时更新;screen.width 和 screen.height 则返回设备物理屏幕逻辑像素尺寸,不随横竖屏自动变化;推荐布局适配用 innerWidth + resize 事件(需防抖),断点判断优先用 matchMedia,调试硬件才用 screen。
window.innerWidth 和 window.innerHeight 获取视口尺寸这是最常用、最可靠的方式,返回的是当前浏览器窗口的可视区域(不含滚动条)宽高,单位为像素。它响应式强,页面缩放或窗口拖拽时会实时变化。
注意:不是设备物理屏幕尺寸,而是用户当前看到的“窗口”大小。移动端横竖屏切换时也会立即更新。
window.innerWidth 包含垂直滚动条宽度(Chrome/Firefox),Safari 则不包含 —— 如果需要精确布局,建议用 document.documentElement.clientWidth 替代(它始终排除滚动条)window 对象,直接访问会报 ReferenceError: window is not defined
console.log(window.innerWidth); // 例如:375(iPhone 竖屏) console.log(window.innerHeight); // 例如:667
screen.width 和 screen.height 获取设备屏幕原始分辨率这两个属性返回的是设备物理屏幕的完整像素尺寸,和浏览器窗口无关。但要注意:它们不随横竖屏旋转而自动更新(iOS Safari 尤其明显),且受系统缩放、DPR 影响,数值未必等于 CSS 像素。
screen.width / screen.height 是只读的,不可写window.devicePixelRatio:例如 screen.width * window.devicePixelRatio 是近似物理宽度(但仍有平台差异)console.log(screen.width); // 例如:414(逻辑像素,非物理) console.log(screen.height); // 例如:896 console.log(window.devicePixelRatio); // 例如:3(iPhone 13)
resize 事件而非轮询不要用 setInterval 定期查 innerWidth —— 开销大且不精准。浏览器原生 resize 事件更高效,但触发频繁,需防抖。
resize,不一定代表用户真的拖动了窗口addEventListener 绑定,避免覆盖已有监听器;销毁时用 removeEventListener(需保留函数引用)function handleResize() {
console.log('视口变为:', window.innerWidth, 'x', window.innerHeight);
}
window.addEventListener('resize', handleResize);
// 初始化
handleResize();matchMedia 做媒体查询检测硬编码 if (width > 768) 容易失效 —— 比如 iPad Pro 横屏时 innerWidth 可能达 1024,但实际是移动体验。CSS 媒体查询才是语义化标准。
matchMedia('(max-width:
768px)') 返回 MediaQueryList 对象,.matches 属性即当前是否匹配mediaQuery.addListener(handler)(旧 API)或 mediaQuery.addEventListener('change', handler)(新 API)innerWidth 更健壮:它和 CSS 渲染引擎同步,不受 JS 执行时机影响const mobileQuery = window.matchMedia('(max-width: 768px)');
console.log(mobileQuery.matches); // true 或 false
mobileQuery.addEventListener('change', e => {
console.log('断点状态变更:', e.matches);
});设备像素比、缩放、iframe 嵌套、SSR 环境、键盘弹出……这些因素会让“屏幕尺寸”变成一个上下文敏感的值。没有银弹,得根据具体场景选 API:布局适配用 innerWidth + resize,设计断点用 matchMedia,调试硬件能力才碰 screen。