matchmedia 是浏览器原生 javascript api,用于在 js 中读取和监听 css 媒体查询状态;它返回 mediaquerylist 对象,含 matches 属性和 addeventlistener 方法,实现对视口尺寸、深色模式、横竖屏等的动态响应,比 resize 轮询更精准高效。

matchMedia 是什么,它和 CSS 媒体查询是什么关系
matchMedia 是浏览器原生 API,用于在 JavaScript 中读取和监听 CSS 媒体查询的状态(比如 (max-width: 768px) 是否匹配当前视口)。它不依赖框架或库,所有现代浏览器都支持(IE10+,但 IE 不支持 addEventListener 方式监听,需用 addListener)。
关键点:它返回一个 MediaQueryList 对象,该对象有 matches 属性(布尔值),还有监听能力——这才是动态响应的核心。
如何正确监听媒体查询变化(避免漏触发或重复绑定)
监听必须用 addEventListener(推荐)或旧版 addListener;直接轮询 matches 是低效且不可靠的。
- ✅ 正确写法:
const mql = window.matchMedia('(prefers-color-scheme: dark)'); mql.addEventListener('change', handler); - ❌ 错误写法:
setInterval(() => { if (mql.matches) {...} }, 100)—— 浪费资源,且可能错过快速切换 - ⚠️ 注意:
change事件只在匹配状态翻转时触发(true ↔ false),不是每次 resize 都发 - ⚠️ 绑定前先检查初始状态:
if (mql.matches) handler();,否则页面加载时可能漏掉首次匹配
常见使用场景与对应 media query 示例
不同用途要选对媒体查询字符串,否则监听无效或行为反直觉:
- 响应式断点:
window.matchMedia('(min-width: 1024px)')—— 适合控制桌面端组件显隐 - 深色模式检测:
window.matchMedia('(prefers-color-scheme: dark)')—— 注意 Safari 早期版本需加-webkit-前缀(现已基本不用) - 减少动画偏好:
window.matchMedia('(prefers-reduced-motion: reduce)')—— 可用来禁用 CSS 过渡或 JS 动画 - 横竖屏判断:
window.matchMedia('(orientation: landscape)')—— 注意:仅在设备旋转时触发 change,不是 resize
怎么安全地移除监听器(容易被忽略的内存泄漏点)
removeEventListener 必须传入与 addEventListener 完全相同的函数引用;匿名函数无法被移除。
- ❌ 错误:
mql.addEventListener('change', () => {...}); mql.removeEventListener('change', () => {...});—— 两个箭头函数是不同引用 - ✅ 正确:把 handler 声明为具名函数或变量:
const handler = () => {...}; mql.addEventListener('change', handler); ... mql.removeEventListener('change', handler); - ? 在单页应用中,组件卸载(如 React useEffect cleanup、Vue onUnmounted)时务必调用
removeEventListener,否则监听器持续存在,mql也难以被 GC - ? 补充:IE10/11 用
mql.removeListener(handler)替代removeEventListener
真正要注意的是:监听器本身不会自动销毁,matchMedia 返回的对象也不会随 DOM 卸载而失效。只要没手动解绑,它就一直挂着——哪怕对应元素早已从页面消失。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











