背景
一讲到媒体查询,大家首先想到的可能都是都是CSS中@media
,这也没错,这确实是最常见的媒体查询方式,但是我们今天要讲的不是它,而是大家很少接触到的window.matchMedia()
和window.resize
最近在做项目的时候拿到一个需求,是要在窗口变化时去根据不同的窗口大小去发送不同的请求,拿到需求的时候我脑袋一蒙,媒体查询不都是在css里面吗,但是网络请求在JavaScript里面啊,难道要在css里去发送网络请求?这当然是不可能的啦。当即我就去MDN查询API了,让我查到了window.matchMedia()
、window.innerWidth
、window.innerHeight
。
window.matchMedia()用法
Window
的matchMedia()
方法可以帮助我们在JavaScript中创建媒体查询对象,它可以帮助我们检查当前视口是否匹配指定的媒体查询条件。方法接受一个参数,即表示媒体查询的字符串,这个字符串遵循CSS中媒体查询的语法规则。
方法返回一个新的
MediaQueryList
对象,表示指定的媒体查询 (en-US)字符串解析后的结果。返回的MediaQueryList
可被用于判定Document
是否匹配媒体查询,或者监控一个document
来判定它匹配了或者停止匹配了此媒体查询。
语法
const mediaQueryList = window.matchMedia(mediaQueryString);
参数
mediaQueryString
:表示媒体查询条件的字符串。它包含一个或多个媒体特性和条件,用来定义在何种视口条件下匹配媒体查询。这个字符串类似于在CSS中使用的媒体查询。
返回值
window.matchMedia()
返回一个对象,通常是一个 MediaQueryList
对象,该对象包含了媒体查询条件的信息。MediaQueryList
对象具有以下属性和方法:
-
matches
属性:一个布尔值,表示当前视口是否匹配指定的媒体查询条件。如果匹配,它将返回true
,否则返回false
。这是一个只读属性,用于立即检查匹配状态。 -
media
属性:包含原始的媒体查询字符串,即传递给window.matchMedia()
的参数。它用于表示媒体查询的条件。 -
addListener(callback)
方法:用于添加一个事件监听器,当媒体查询条件的匹配状态发生变化时,将触发指定的回调函数。 -
removeListener(callback)
方法:用于从MediaQueryList
对象上移除特定的事件监听器。
MediaQueryList
对象的主要用途是检查当前视口的媒体查询条件是否匹配,并在条件变化时监听事件以执行相应的操作。
下面我们来用代码演示一下window.matchMedia()
如何使用
matches
属性
// 定义媒体查询条件
const mediaQueryString = "(max-width: 600px)";
// 创建媒体查询对象
const mediaQueryList = window.matchMedia(mediaQueryString);
// 检查当前视口是否匹配媒体查询条件
if (mediaQueryList.matches) {
console.log("视口宽度小于等于600px");
} else {
console.log("视口宽度大于600px");
}
addListener(callback)
方法和 removeListener(callback)
方法
// 添加事件监听器来监听媒体查询条件的变化
function handleMediaQueryChange(event) {
if (event.matches) {
console.log("视口宽度小于等于600px");
} else {
console.log("视口宽度大于600px");
}
}
// 添加事件监听器
mediaQueryList.addListener(handleMediaQueryChange);
// 移除事件监听器
setTimeout(() => {
mediaQueryList.removeListener(handleMediaQueryChange);
console.log("事件监听器已移除");
}, 5000);
点击右上角的查看详情,即可查看源代码
jcode
window.innerWidth
和 window.innerHeight
window.innerWidth
和window.innerHeight
是 JavaScript 中用于获取当前视口的宽度和高度的属性。
-
window.innerWidth
:- 用法:
window.innerWidth
是一个只读属性,用于获取当前视口的宽度,单位为像素。 - 返回值:
window.innerWidth
返回一个整数,表示当前视口的宽度。
代码示例:
- 用法:
function widthChangeCallback() {
if(window.innerWidth > 599) {
show.innerHTML = `<div class="large">我比599px大</div>`;
} else {
show.innerHTML = `<div class="small">我比599px小</div>`;
}
}
window.addEventListener('resize', widthChangeCallback);
widthChangeCallback();
-
window.innerHeight
:- 用法:
window.innerHeight
是一个只读属性,用于获取当前视口的高度,单位为像素。 - 返回值:
window.innerHeight
返回一个整数,表示当前视口的高度。
代码示例:
// 获取当前视口高度 const viewportHeight = window.innerHeight; if (viewportHeight <= 400) { console.log("视口高度小于等于400px"); } else { console.log("视口高度大于400px"); }
- 用法:
点击右上角的查看详情,即可查看源代码
jcode
性能对比
既然两种方案都能实现,所以我们很自然地想知道它们中的哪一个能提供更好的性能,以及我们应该在什么时候使用这些解决方案中的每一个。
每当窗口大小发生变化时,widthChangeCallback()
函数都会被调用,通过大小变化事件侦听器触发。这种方式适用于每个实例都需要响应窗口大小变化的情况,例如画布的更新。
但是,在某些特定情况下,只有当宽度或高度达到特定的阈值时,才需要执行某些操作。举个例子,就像我们前面提到的文本更新。在这种情况下,使用matchMedia()
将能够提供更佳的性能,因为它只在媒体查询条件实际更改时触发回调函数,避免了不必要的计算。
点击右上角的查看详情,即可查看源代码
jcode
从上面我们可以看出两者的回调执行次数差异巨大,所以我们在开发过程中应当根据业务的实际需求去选择使用哪一个API。
总结
我们了解到,借助该matchMedia()
方法,我们在 CSS 中经常使用的媒体查询现在也可以在 JavaScript 中使用。并且使用matchMedia()
可以为我们提供更好的性能,而不是在window
上添加事件侦听器resize
。与依赖于window
做一些事情的旧方法相比,我们可以使用媒体查询执行更多检查。