你知道吗?Javascript也有媒体查询API

601 阅读2分钟

当您想到媒体查询时,想到的第一件事是什么?也许 CSS 文件中的内容如下所示:

body {
  background-color: red;
}

@media (min-width: 768px) {
  body {
    background-color: blue;
  }
}

CSS 媒体查询是我们在做响应式设计的核心要素。可以让我们根据设备显示器的特性(如视口宽度、屏幕比例、设备方向:横向或纵向)为其设定CSS样式,解决不同设备显示器 UI 适配问题,为不同设备类型的用户提供了最佳的视觉体验。

但是您知道 JavaScript 也有媒体查询的 API 吗?尽管我们用的少,但是真有,在 Javascript 中使用媒体查询对创建响应式元素非常方便,例如,在某个分辨率下,我们可能需要重新绘制并重新计算响应式元素大小。

matchMedia()

浏览器支持情况:

用法几乎与CSS媒体查询相同。我们将媒体查询字符串传递给matchMedia()。

const mediaQuery = window.matchMedia('(min-width: 768px)')

定义的媒体查询将返回一个MediaQueryList对象。该对象存储有关媒体查询的信息,而我们可以通过返回对象的matches属性来判断是否匹配。

const mediaQuery = window.matchMedia('(min-width: 768px)')
if (mediaQuery.matches) {
  console.log('matchMedia')
}

addListener()

MediaQueryList 内置有 addListener() 和 removeListener() 方法,这两个方法是媒体查询状态更改时回调函数。当判断条件匹配时,我们可以触发自定义事件,从而使我们能够及时响应。

const mediaQuery = window.matchMedia('(min-width: 768px)')
function handleTabletChange(e) {
 if (e.matches) {
   console.log('Media Query Matched!')
 }
}
mediaQuery.addListener(handleTabletChange)
handleTabletChange(mediaQuery)

注:第一次加载时,addListener() 默认不会调用。如果我们需要启动时调用,需要手动调用事件处理程序函数,并将媒体查询作为参数传递调用。

handleTabletChange(mediaQuery)

和 resize 的区别

以前监听窗口,我们最常用的做法是使用 resize,通过绑定 resize 事件监听检查window.innerWidth 或 window.innerHeight 。

function checkMediaQuery() {
 if (window.innerWidth > 768) {
   console.log('resize')
 }
}
window.addEventListener('resize', checkMediaQuery);

由于每次浏览器调整大小都会调用 resize 事件,因此这是一项非常耗性能的做法!通过对比我们可以看到差异。调用 resize 缩放窗口共执行了 57 次,而通过 matchMedia 值执行了一次。

function checkMediaQuery() {
    if (window.innerWidth > 768) {
        console.log('resize!')
    }
}
window.addEventListener('resize', checkMediaQuery);
const mediaQuery = window.matchMedia('(max-width: 768px)')
function handleTabletChange(e) {
    if (e.matches) {
        console.log('matchMedia!')
    }
}
mediaQuery.addListener(handleTabletChange)
handleTabletChange(mediaQuery);

其次,通过 resize 只能通过window.innerWidth 或 window.innerHeight监听屏幕变化,而使用 matchMedia() 你可以传入 css 媒体查询的判断属性,如 设备宽高比(device-aspect-ratio)、宽高比(aspect-ratio)、方向(orientation)等,在用法上更加灵活。

const mediaQuery = window.matchMedia('(min-aspect-ratio: 1/1)')
const mediaQuery = window.matchMedia('(orientation: portrait)')

本文原文地址:www.mn1024.com/20056884.ht…