JavaScript 中的 CSS @media 规则
CSS API 回顾
CSS规则
CSS媒体规则
反过来
匹配媒体
结论
在 Web 技术方面,JavaScript 占据着非常特殊的地位。它既能提供其他语言无法提供的功能,又能轻松取代其他 Web 语言——也就是 HTML 和 CSS。
虽然大多数 JS 开发人员可能都知道 DOM API 以及在其上构建的所有 UI 库和框架,但对“CSS API”(技术上它不是这样称呼的,但你明白我的意思)的了解却不那么普遍。
在上一篇文章中,我已经介绍了可以直接在 JS 中使用 API 创建 CSS 样式表。今天,我想讲讲更高级的内容——如何@media
在 JS 中控制 CSS 规则(你猜对了!)!
CSS API 回顾
让我们首先快速回顾一下上一篇文章。
您可以通过两种方式访问样式表 - 通过标签 DOM 元素sheet
的属性<style>
,或作为索引集合中的项目之一document.styleSheets
。在这两种情况下,结果都是一个实现CSSStyleSheet
接口的对象,该对象允许您进一步访问控制方法(例如insertRule()
和removeRule()
)以及属性(例如cssRules
)。
const style = document.createElement("style");
document.head.appendChild(style);
const styleSheet = style.sheet;
const ruleIndex = styleSheet.insertRule(".example { background-color: red }");
const rule = styleSheet.cssRules[ruleIndex];
该insertRule()
方法返回新 CSS 规则插入的索引。之后,可以使用该索引来访问实现该CSSRule
接口的规则对象。正如预期的那样,该对象本身也有一些属性,主要用于配置和访问规则的数据。
CSS规则
现在,我们稍微放慢速度。这是因为CSSRule
必须充分理解 及其派生类,才能创建更复杂的基于 JS 的样式表。
它本身——尽管你永远不会看到它——CSSRule
只有几个属性。最重要的可能是cssText
- 保存规则的文本 CSS 表示和type
- 指示给定 类型的常量值CSSRule
。
// ...
rule.cssText; // ".example { background-color: red; }"
该接口有多种类型,因此也衍生出多种类型CSSRule
。最常见的是 -CSSStyleRule
负责像上面那样的规则。除了标准CSSRule
属性外,它还有一些更有趣的属性,例如selectorText
- 规则 CSS 选择器的文本表示,以及style
-CSSStyleDeclaration
对象,就像您可能熟悉的 DOM 元素的内联样式一样。
// ...
rule.selectorText; // ".example"
rule.style.backgroundColor; // "red"
rule.style.backgroundColor = "green";
rule.style.backgroundColor; // "green"
作为一项不错的奖励 - 您是否知道您可以更改style
规则,实时修改规则以及应用规则的所有元素!?
CSS媒体规则
但所有这些不同的CSSRule
s 都不是你来这里的目的——不。你来这里是为了 CSS@media
规则。而且,正如你所料,它在 JavaScript 端也有体现——这次是以 的形式CSSMediaRule
。
CSSMediaRule
之所以如此有趣,是因为它继承了更深的层次。与CSSStyleRule
作为 直接子级的simple 不同CSSRule
,CSSMediaRule
它还拥有CSSGroupingRule
和CSSConditionRule
(按给定顺序)作为其父级。
这充分说明了规则的含义。CSSGroupingRule
表示包含嵌套规则的规则,而CSSConditionRule
表示仅在满足特定条件时才应用。还记得 CSS@media
规则的语法吗?
@media screen and (min-width: 900px) {
.example {
background-color: blue;
}
}
现在,CSSMediaRule
父类和子类都为其添加了重要的属性和方法。从上往下(在CSSRule
自身正下方),父类会为该子类添加诸如和之类CSSGroupingRule
的方法以及属性。听起来很熟悉?因为这些功能与我们之前看到的类似,都是从界面开始的。insertRule()
deleteRule()
cssRules
CSSStyleSheet
// ...
const mediaRuleText = `@media screen and (min-width: 900px) {
.example {
background-color: blue;
}
}`;
const mediaRuleIndex = styleSheet.insertRule(ruleText);
const mediaRule = styleSheet.cssRules[mediaRuleIndex];
mediaRule.cssRules[0].selectorText; // ".example"
mediaRule.cssRules[0].style.backgroundColor; // "blue"
在我们的例子中,只有 1 条由CSSGroupingRule
简单分组的规则CSSStyleRule
,这意味着我们已经完成了一个完整的循环。
接下来,我们得到了CSSConditionRule
带有conditionText
属性的 。它允许我们访问 CSS 条件的文本表示。在我们的例子中,它是:
mediaRule.conditionText; // "screen and (min-width: 900px)"
还会CSSMediaRule
添加一个自己的属性 - media
- 相当于一个实现了MediaList
接口的对象。基本上,这是一个更高级的版本conditionText
。它其实并不重要,所以如果你感兴趣的话,可以查看 MDN 文档。
反过来
好了,关于 CSS 和相关 API 的内容基本就到此为止了CSSMediaRule
。像这个 API 这样的变体有很多,如果搭配使用,效果会非常显著。像我自己的PrototopeCSSRule
这样动态、可管理的 CSS-in-JS 库,具备复杂的实时更新功能,绝对是可行的。
但你或许会说,这些事情最好用 CSS 来处理。你完全正确——CSS 的设计初衷就是如此。但如果是这样,或许你会对其他东西感兴趣?
如果我告诉你,有一种方法可以直接在 JS 中执行媒体查询?比如,知道窗口何时达到了所需的宽度或高度?嗯,这当然是可能的,而且这一切都归功于matchMedia()
匹配媒体
因此,matchMedia()
这是一种可在对象上直接访问window
(全局)的方法,它允许您解析给定的媒体查询并对其活动中的变化做出反应。
const mediaQuery = matchMedia("screen and (min-width: 900px)");
matchMedia()
返回一个MediaQueryList
对象。这个对象提供了使用媒体查询所需的一切。它包含最重要的matches
属性,用于检查媒体查询是否与当前网站的状态匹配;media
属性,用于返回提供的媒体查询字符串;以及两个addListener()
和两个removeListener()
方法来监听媒体查询状态的变化。
mediaQuery.addListener(() => {
mediaQuery.matches; // true or false
});
mediaQuery.media; // "screen and (min-width: 900px)"
现在,您无可否认这个功能的实用性。能够检查特定媒体查询是否适用,在处理任何类型的 JS 驱动 UI 时都极其有用——例如 Masonry Grid。这种方法比任何其他类似的解决方案(尤其是那些需要持续事件监控的解决方案)matchMedia()
都要快得多resize
。而且,我之前说过,它对 IE 10 及以上(或者更确切地说是最低)浏览器都有很好的跨浏览器支持!
结论
借助 CSS API,matchMedia()
我想我已经向你展示了 JavaScript 功能令人印象深刻的一面。希望你学到了一些新知识,现在能够创建各种 JS 奇迹——从简单的 JS 驱动的 UI 布局到功能齐全的 CSS-in-JS 库。
想要了解更多 Web 开发指南和教程,请在Twitter、Facebook或 Dev.to 上关注我。我还有一个YouTube 频道(最近不太活跃,但我正在努力维护),你可以去看看并订阅。感谢阅读这篇文章,祝你编程愉快!
文章来源:https://dev.to/areknawo/css-media-rule-in-javascript-5de