什么是MediaQueryList
一个MediaQueryList对象在一个document上维持着一系列的媒体查询,并负责处理当媒体查询在其document上发生变化时向监听器进行通知的发送。
如果你需要以编程方式来检测一个document上的媒体查询的值的变化,这个MediaQueryList对象使得通过观察其document而检测它的媒体查询的值的变化成为可能,而不是周期性地对这些媒体查询的值进行检查。
简单来说,MediaQueryList就是提供给JavaScript进行媒体查询的方法
兼容性方面也挺好

先来看看MediaQueryList的属性和方法
属性
matches返回媒体查询的结果media返回媒体查询的内容onchange媒体查询状态变化时触发的事件
方法
addListener()当媒体查询状态变化时触发的自定义回调removeListener()移除自定义回调
matches
matches是MediaQueryList的只读属性,返回一个布尔值,当媒体查询匹配时返回ture,反之false
先要创建一个MediaQueryList对象
const mql = window.matchMedia("(max-width:1600px)");通过matches属性获取媒体查询的结果
if (mql.matches) console.log("屏幕宽度小于1600px"); // 如果刚好1600也返回true
else console.log("屏幕宽度大于1600px");通过这个方式可以很容易的判断当前系统的主题
let pref = window.matchMedia("(prefers-color-scheme: light)");
if (pref.matches) console.log("light");
pref = window.matchMedia("(prefers-color-scheme: dark)");
if (pref.matches) console.log("dark");在实现页面主题的切换功能时可以用到
media
media属性会返回填写的媒体查询匹配规则
const mql = window.matchMedia("(max-width:1600px)");
console.log(mql.media); // (max-width: 1600px)addListener/removeListener
addListener添加自定义回调,在媒体查询的状态改变时会调用回调
const mql = window.matchMedia("(max-width:1600px)");
const cb = e => {
if (e.matches) console.log("屏幕宽度小于1600px");
else console.log("屏幕宽度大于1600px");
};
mql.addListener(cb);
// 移除回调函数
mql.removeListener(cb);在页面加载完成后,不会触发此回调,一定得手动拖动窗口大小后才会触发
有小伙伴就要问了,onchange属性呢,且容我细细道来
onchange
先来看代码
const mql = window.matchMedia("(max-width:1600px)");
const cb = e => {
if (e.matches) console.log("屏幕宽度小于1600px");
else console.log("屏幕宽度大于1600px");
};
mql.onchange = cb;在Chrome上一切正常,然而在Safari上毫无反应
在看看Can i use

为什么兼容性突然就变成这样了?
在使用addListener的时候,我发现了在Webstorm里addListener居然划了横线标注了废弃的方法

不仅addListener,removeListener也废弃了,同时发现了两个新方法addEventListener和removeEventListener
addEventListener/removeEventListener
addEventListener的使用方式和DOM2级事件绑定方式相同
const mql = window.matchMedia("(max-width:1600px)");
const cb = e => {
if (e.matches) console.log("屏幕宽度小于1600px");
else console.log("屏幕宽度大于1600px");
};
mql.addEventListener("change", cb);
// mql.removeEventListener("change", cb);在Chrome上一切正常,在Safafi上就报错了mql.addEventListener is not a function,这也许能解释为什么onchange兼容性不好了
同时我发现,使用addListener方法添加的事件,参数e在Chrome上和Safari上也是两个不同的东西
在Chrome上,它是一个Event对象,在Safari上只是包含了matches和media属性的对象,在看看兼容性

看上去Chrome也是才支持的
在MDN上是这样写的
MediaQueryList.addListener()方法只是为了向后兼容
EventTarget.addEventListener()的一个别名,在老的浏览器上应该使用addListener而不是addEventListener,因为MediaQueryList只从新的浏览器继承EventTarget
我想这只是为了规范化吧,看来新的浏览器Chrome 80也不够新啊,还是老老实实看着标灰划个线用addListener就行了
参考资料:
MDN:https://developer.mozilla.org/zh-CN/docs/Web/API/MediaQueryList