MediaQueryList 接口是媒体查询响应式核心,window.matchMedia()仅是创建其实例的工厂函数;它提供matches属性和addEventListener()方法实现状态监听,需手动检查初始状态且注意语法正确性。

MediaQueryList 接口是核心,不是 window.matchMedia() 本身
很多人以为 window.matchMedia() 是“媒体查询 API”,其实它只是创建 MediaQueryList 实例的工厂函数。真正响应变化、承载状态的是返回的 MediaQueryList 对象——它有 matches 属性和 addEventListener() 方法,这才是可监听、可响应的关键。
直接读 window.matchMedia('(max-width: 768px)').matches 只能取快照,不监听;必须用 addListener()(旧)或 addEventListener('change', ...)(新)才能响应尺寸变化。
-
addListener()在 Chrome 109+、Firefox 117+ 已被弃用,但仍有大量老项目在用,兼容性需留意 -
addEventListener()是标准方式,但 IE 完全不支持,如需支持 IE,必须降级 fallback -
MediaQueryList实例可复用:同一查询字符串多次调用matchMedia()返回不同对象,不要重复创建监听器
监听屏幕尺寸变化的最小可行代码
下面这段代码在现代浏览器中稳定工作,监听从桌面到移动的切换:
const mql = window.matchMedia('(max-width: 768px)');
const handleMediaChange = (e) => {
if (e.matches) {
console.log('进入移动端视图');
} else {
console.log('回到桌面视图');
}
};
// 使用 addEventListener(推荐)
mql.addEventListener('change', handleMediaChange);
// 初始状态也要检查(change 不触发初始匹配)
if (mql.matches) {
handleMediaChange(mql);
}
注意:不能只靠事件回调判断初始状态——change 只在查询结果翻转时触发,页面加载时可能已处于目标断点内,必须手动检查 mql.matches 并调用一次处理函数。
立即学习“Java免费学习笔记(深入)”;
常见错误:把 media query 字符串写错或漏括号
错误写法会导致 mql.matches 永远为 false,且不报错,极难排查:
-
window.matchMedia('max-width: 768px')❌ 缺少括号 → 应为'(max-width: 768px)' -
window.matchMedia('(min-width: 768px) and (max-width: 1024px)')✅ 正确,多条件用and连接 window.matchMedia('(width ❌ CSS 媒体查询不支持运算符写法- 使用
screen、print等媒体类型时,必须写全:'screen and (max-width: 768px)'
调试技巧:打印 mql.media 看实际解析的字符串,确认是否与预期一致。
性能与内存:监听器没清理会泄漏
组件卸载(如 React unmount、Vue destroyed)时,若没移除监听器,MediaQueryList 仍持有回调引用,可能导致闭包中 DOM 节点无法回收。
- 对应添加监听器的地方,必须配套清理:
mql.removeEventListener('change', handleMediaChange) - 使用
addListener()时,用removeListener()配对,不能混用 - React 中建议在
useEffect的 cleanup 函数里移除;Vue 3 的onBeforeUnmount同理 - 临时监听(比如只在弹窗打开期间响应)更要主动管理生命周期
一个容易被忽略的点:MediaQueryList 本身不会自动销毁,哪怕窗口关闭或 iframe 卸载,只要 JS 上下文还在,它就持续存在。










