使用 JavaScript 中的媒体查询

今天很多互联网浏览都发生在移动设备上,它们有各种大小。这意味着您开发的任何网站都需要在所有这些尺寸下看起来都很棒。换句话说,网站必须具有响应性,以便其布局可以响应屏幕宽度的任何变化而变化。

在 CSS 中使用媒体查询

使网站响应的一种流行方法是在 CSS 中使用媒体查询。使用媒体查询允许我们指定哪些 CSS 规则应该应用于特定屏幕宽度的元素。这包括更改font-size移动设备上的标题或段落文本等内容。

考虑以下 CSS 片段:

h1 {

font-family: 'Lato';

font-size: 2rem;

text-transform: uppercase;

color: green;

}

@media (min-width: 600px) {

h1 {

font-size: 4rem;

}

}


我们使用 CSS 告诉浏览器标题需要是绿色的,并且字体大小必须为 2rem。但是,当屏幕宽度大于 600px 时,字体大小需要增加到 4rem。所有其他 CSS 属性的值将保持不变。通过玩下面的 CodePen 演示,您可以看到现实生活中也会发生这种情况:

在 JavaScript 中使用媒体查询

我们可以使用我们上面在 JavaScript 代码中使用的相同媒体查询。matchMedia()借助您可以调用的方法,这已成为可能window

matchMedia()方法接受单个参数作为其值,即您要检查的媒体查询。继续我们在上一节中的示例,调用matchMedia()如下所示:

let myMediaQuery = window.matchMedia('(min-width: 600px)');

调用此方法会返回一个MediaQueryList对象,其中包含有关您在文档上应用的媒体查询的信息。它包含两个属性。第一个是media,它将媒体查询存储为序列化字符串。第二个是matches,它基本上是一个布尔值,true如果我们作为参数提供的媒体查询与文档匹配,则返回该值。

调用matchMedia()本身不会做太多事情。您需要检查调用返回matches的对象的属性是否是或进行您自己的操作。即使这样,您也只能在初始页面加载时检查是否满足媒体查询条件。MediaQueryListtruefalse

如果用户在初始加载后改变了屏幕宽度怎么办?您如何检测到这种变化并采取相应的行动?这就是事件监听器将帮助我们的地方。

有两种方法可供您调用addListener()removeListener()您可以使用它们来监听媒体查询状态的任何变化。但是,它们现在已被弃用。

您现在应该考虑使用该方法将change事件附加到MediaQueryList对象。addEventListener()这是回调的样子:

let myMediaQuery = window.matchMedia('(min-width: 600px)');

function widthChangeCallback(myMediaQuery) {

if(myMediaQuery.matches) {

document.querySelector("p").textContent = "I am wider than 599px now.";

} else {

document.querySelector("p").textContent = "I am narrower than 599px now.";

}

}

myMediaQuery.addEventListener('change', widthChangeCallback);



当您调整窗口大小并更新文本以显示有关宽度的相应消息时,上面的代码将跟踪屏幕宽度。

上面代码中唯一缺少的是初始检查以查看在页面加载但未发生调整大小时是否满足媒体查询。我们可以第一次检查我自己执行的回调。

widthChangeCallback(myMediaQuery);

窗口resize事件监听器与matchMedia

该方法的另一种替代matchMedia()方法涉及将resize事件侦听器附加到窗口。很容易更新上一节中的代码以使用 resize 事件侦听器,它看起来像这样:

function widthChangeCallback() {

if(window.innerWidth > 599) {

document.querySelector("p").textContent = "I am wider than 599px now.";

} else {

document.querySelector("p").textContent = "I am narrower than 599px now.";

}

}

window.addEventListener('resize', widthChangeCallback);

widthChangeCallback();

这一次,我们使用该innerWidth属性来检查宽度是否大于 599 并相应地更新文本。下面的 CodePen 演示显示我们仍然拥有使用matchMedia().

很自然地想知道它们中的哪一个提供了更好的性能,以及何时应该使用这些解决方案中的任何一个。

比较性能

widthChangeCallback()每次调整窗口大小时,resize 事件侦听器都会触发该函数。这仅在您需要响应窗口大小更改的每个实例(例如更新画布)的某些情况下才需要。

但是,在某些情况下,只有当宽度或高度达到某个阈值时才需要发生某些事情。一个例子是我们上面所做的文本更新。在这种情况下,您将获得更好的性能,matchMedia()因为它仅在媒体查询条件的实际更改时触发回调。

查询复杂度

使用matchMedia()方法允许您利用媒体查询提供的所有功能和灵活性。resize通过简单地使用事件监听器,这可能非常困难或完全不可能复制。

虽然在使用传统的 resize 事件侦听器时您受限于宽度和高度,但您可以使用该方法检查更多内容matchMedia()。除了屏幕宽度和高度,您还可以使用媒体查询来检查屏幕分辨率、纵横比、每个颜色分量的位数、方向等。

您还可以在定义媒体查询时组合多个条件。您可以使用的逻辑运算符包括notandonly。例如,您可以像这样定义媒体查询:

(min-width: 600px) and (max-width: 800px)

现在,将更改事件侦听器附加到我们的媒体查询对象将在两个不同的断点处执行回调。

假设我们最初以 1000px 的宽度开始,然后开始缩小窗口。当宽度第一次下降到 800px 时将触发回调。这是因为最大允许宽度为 800 像素。当屏幕宽度下降到 599px 时,接下来会触发回调。这是因为 600px 的最小宽度仍然是可以接受的,并且媒体查询的状态只有在宽度达到 599px 时才会改变。

假设您下降到 400px 的宽度,然后再次开始增加宽度。现在当屏幕宽度达到 600px 时会触发媒体查询回调。继续增加尺寸,你会看到当你达到 801px 的宽度时会触发第四个回调。

您还可以使用其他媒体查询的组合,例如aspect-ratioresolution进行检查。纵横比是视口的宽度与高度的比率。因此,高宽比值意味着设备处于横向模式。同样,纵横比的低值意味着设备处于纵向模式。orientation媒体查询以类似的方式工作,其中值指示portrait设备宽度小于或等于高度。

如果您正在开发一个游戏,您需要设备处于横向模式并且还需要检查其分辨率以加载适当的资源,您可以MediaQueryList使用以下代码创建适当的对象:

let myMediaQuery = window.matchMedia('(min-resolution: 200dpi) and (min-aspect-ratio: 16/9)');

function matchMediaCallback(myMediaQuery) {

if(myMediaQuery.matches) {

document.querySelector("p").textContent = "Loading game resources..";

} else {

document.querySelector("p").textContent = "Please rotate your device";

}

}

myMediaQuery.addEventListener('change', matchMediaCallback);

matchMediaCallback(myMediaQuery);



最后的想法

在本教程中,我们涵盖了您需要了解的有关matchMedia()方法和在 JavaScript 中使用媒体查询的所有内容。我们了解到,我们在 CSS 中使用了一段时间的媒体查询现在也可以借助该matchMedia()方法在 JavaScript 中使用。

我们了解到 using 可以matchMedia()提供更好的性能,而不是resize在窗口上添加事件侦听器。类似地,我们可以对媒体查询执行更多检查,而旧方法则依赖于innerWidth窗口来做一些事情。

最后,我想补充一点,它matchMedia()拥有超过 98% 的非常好的浏览器支持。仍然建议确保目标受众安装的浏览器支持在 JavaScript 中使用媒体查询。

发表评论
留言与评论(共有 0 条评论) “”
   
验证码:

相关文章

推荐文章