JavaScript响应式设计需结合resize节流与matchMedia:先用throttle控制resize高频触发,再用matchMedia精准监听断点变化,并在初始化和卸载时分别执行与清理。

JavaScript 响应式设计的核心不是仅靠 CSS 媒体查询,而是让 JS 行为能随视口尺寸动态调整。监听窗口大小变化是其中最基础也最关键的一步。
使用 resize 事件监听窗口尺寸变化
浏览器的 window 对象提供 resize 事件,只要用户改变浏览器窗口宽度或高度,就会触发:
- 直接绑定:
window.addEventListener('resize', handler) - 注意:该事件会高频触发(拖拽窗口时每秒可能几十次),不加节流易导致性能问题
- 简单示例:
function handleResize() {
console.log('当前宽度:', window.innerWidth);
}
window.addEventListener('resize', handleResize);务必添加节流(throttle)避免性能损耗
频繁执行重计算、DOM 操作或请求时,不节流会导致卡顿甚至页面崩溃:
- 推荐使用固定间隔限制执行频率(如 150ms 内最多执行一次)
- 可手写简易节流函数,也可用 Lodash 的
throttle或现代浏览器的requestAnimationFrame方案 - 轻量节流示例:
function throttle(fn, delay) {
let last = 0;
return function(...args) {
const now = Date.now();
if (now - last > delay) {
fn.apply(this, args);
last = now;
}
};
}
const throttledResize = throttle(() => {
if (window.innerWidth < 768) {
document.body.classList.add('mobile');
} else {
document.body.classList.remove('mobile');
}
}, 150);
window.addEventListener('resize', throttledResize);
立即学习“Java免费学习笔记(深入)”;
配合 matchMedia 实现更精准的断点响应
matchMedia 允许 JS 直接读取 CSS 媒体查询状态,比单纯监听 resize 更语义化、更可靠:
- 支持监听媒体查询变化(如
(max-width: 767px)),自动回调 - 首次调用即返回当前匹配状态,无需手动判断
innerWidth - 适合与 CSS 断点保持完全一致的逻辑分支
- 示例:
const mediaQuery = window.matchMedia('(max-width: 767px)');
function onMobileChange(e) {
if (e.matches) {
console.log('进入移动端视图');
} else {
console.log('退出移动端视图');
}
}
// 立即执行一次
onMobileChange(mediaQuery);
// 监听变化
mediaQuery.addListener(onMobileChange); // 旧 API
// 或推荐用 modern 方式:
// mediaQuery.addEventListener('change', onMobileChange);
实际项目中的建议组合用法
真实场景中往往需要兼顾初始化、变化响应和性能:
- 页面加载时立即根据当前视口执行一次适配逻辑(避免 FOUC 或初始错位)
- 用
matchMedia处理明确断点行为(如菜单折叠、组件切换) - 用节流后的
resize处理连续变化相关逻辑(如画布重绘、滚动视差) - 在 SPA 中,记得在组件卸载或页面离开时移除监听器,防止内存泄漏











