JavaScript不直接适配屏幕,而是通过检测(如clientWidth、visualViewport)、响应(resize/orientationchange事件)和补位(动态改class、canvas像素比)实现;需节流监听、区分CSS/物理像素、配合viewport与dpr处理高清屏。

移动端 JavaScript 本身不直接“适配屏幕尺寸”,真正起作用的是 CSS 媒体查询、视口设置和 DOM 操作逻辑;JavaScript 的角色是检测、响应、补位——比如监听 window.resize、读取 window.innerWidth、动态修改 class 或调整 canvas 像素比。
为什么直接用 window.innerWidth 可能不准
在 iOS Safari 和部分安卓浏览器中,window.innerWidth 返回的是 CSS 像素宽度(即 viewport 宽度),不是物理像素,也不包含地址栏临时遮挡导致的缩放抖动。更可靠的方式是结合 document.documentElement.clientWidth 和 visualViewport?.width(新 API,兼容性需查)。
- 地址栏收起/展开时,
window.innerWidth可能短暂跳变,导致布局闪动 - 横屏切换瞬间,某些 Android WebView 未触发 resize 事件,需监听
orientationchange - 使用
visualViewport.width能获取当前可视区域真实 CSS 宽度(含缩放),但 Chrome 61+、Safari 15.4+ 才支持
如何安全监听屏幕尺寸变化
别只依赖 resize 事件——它在移动端触发频繁且不可靠(尤其快速旋转时)。应组合使用 resize + orientationchange + visualViewport?.addEventListener('resize', ...),并加节流。
let resizeTimer;
window.addEventListener('resize', () => {
clearTimeout(resizeTimer);
resizeTimer = setTimeout(() => {
const width = Math.min(document.documentElement.clientWidth, window.innerWidth);
if (width < 480) {
document.body.classList.add('mobile');
} else {
document.body.classList.remove('mobile');
}
}, 150);
});
// 补充监听 orientationchange(iOS 旧版必需)
window.addEventListener('orientationchange', () => {
setTimeout(() => {
// 强制重读,避免 orientationchange 后 clientWidth 还没更新
document.documentElement.style.fontSize = '1px';
document.documentElement.offsetHeight; // 强制重排
}, 0);
});
如何配合 viewport 实现 JS 可控的缩放逻辑
如果业务需要禁止双指缩放但允许 JS 动态控制 zoom(如地图、PDF 查看器),不能只靠 锁死,而要用 visualViewport.scale + transform 模拟。
立即学习“Java免费学习笔记(深入)”;
-
是基础,但会禁用所有缩放,包括 JS 触发的 - 若需保留缩放能力,改用
user-scalable=yes,再用 JS 拦截 touchstart/touchmove 控制visualViewport.scale - 注意:
visualViewport.scale是只读属性,只能通过visualViewport.addEventListener('resize', ...)监听变化,不能直接设值;实际缩放需靠element.style.transform = 'scale(1.5)'+transform-origin配合
适配高清屏(dpr)时 JS 容易漏掉的关键点
很多开发者只做 canvas 的 devicePixelRatio 缩放,却忽略 SVG、CSS 单位、字体渲染等场景。
- canvas 绘图前必须同时设置
canvas.width/canvas.height(物理像素)和canvas.style.width/canvas.style.height(CSS 像素) - SVG 图标若用
,不会自动响应 dpr;应改用内联 SVG 或用srcset提供 2x 版本 - 用 JS 动态设置字体大小时,别写死
16px,可基于window.devicePixelRatio > 1.5微调行高或字重
设备像素比不是越高越好——有些低端安卓机上报 devicePixelRatio=3 但 GPU 性能跟不上,强行提升 canvas 分辨率反而卡顿。










