# MediaQueryList

  • 定义

包含一个布尔值 matches 和字符串 media 的对象:

{
  matches: true,
    media: "(600px < width < 2000px)",
    onchange: null
}
  • 说明
    • matches:一个布尔值,如果当前 document 与媒体查询列表相匹配,则返回 true,否则返回 false。
    • media:代表序列化的媒体查询的字符串。
    • onchange:当其媒体查询的求值结果发生变化时,改函数将会被调用(需要使用 addEventListener 或赋值绑定)。

# media 属性

  • 定义

HTMLMetaElement.media 属性允许为 theme-color 元数据指定媒体。

theme-color 属性允许在支持此属性的浏览器和操作系统中设置浏览器工具栏或 UI 的颜色。 media 属性允许为不同的 media 值设置不同的主题颜色。

  • 用法

为暗色模式设置主题色

const meta = document.createElement("meta");
meta.name = "theme-color";
meta.content = "#3c790a";
meta.media = "(prefers-color-scheme: dark)";
document.head.appendChild(meta);

以上示例创建一个新的 <meta> 元素,其 name 属性设置为 theme-colorcontent 属性设置为 #3c790amedia 属性设置为 prefers-color-scheme: dark ,并把元素附加到文档 <head> 上。当用户在操作系统中指定暗色模式时,可以使用 media 属性设置不同的 theme-color 。最后会转换成这样的元素:

<meta
  name="theme-color"
  content="#3c790a"
  media="(prefers-color-scheme: dark)"
/>
  • 示例
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <!-- 设置基于系统主题的初始颜色 -->
    <meta
      name="theme-color"
      content="#ffffff"
      media="(prefers-color-scheme: light)"
    />
    <meta
      name="theme-color"
      content="#3c790a"
      media="(prefers-color-scheme: dark)"
    />
    <title>Dynamic Theme Color</title>
    <style>
      body {
        font-family: Arial, sans-serif;
        display: flex;
        flex-direction: column;
        align-items: center;
        justify-content: center;
        height: 100vh;
      }
      .btn-toggle-theme {
        padding: 10px 20px;
        margin-top: 20px;
        cursor: pointer;
      }
    </style>
  </head>
  <body>
    <h1>Dynamic Theme Color Example</h1>
    <button class="btn-toggle-theme" onclick="toggleTheme()">
      Toggle Theme
    </button>
    <script>
      // 获取当前系统主题并应用
      function setThemeColor() {
        const isDarkMode = window.matchMedia(
          "(prefers-color-scheme: dark)"
        ).matches;
        const themeColorMetaTag = document.querySelector(
          'meta[name="theme-color"]'
        );
        themeColorMetaTag.setAttribute(
          "content",
          isDarkMode ? "#3c790a" : "#ffffff"
        );
        document.body.style.backgroundColor = isDarkMode
          ? "#3c790a"
          : "#ffffff";
        document.body.style.color = isDarkMode ? "#ffffff" : "#000000";
      }
      // 监听系统主题的变化
      window
        .matchMedia("(prefers-color-scheme: dark)")
        .addEventListener("change", setThemeColor);
      // 切换主题手动更新颜色
      function toggleTheme() {
        const currentColor = document.body.style.backgroundColor;
        const newColor =
          currentColor === "rgb(60, 121, 10)" ? "#ffffff" : "#3c790a";
        const themeColorMetaTag = document.querySelector(
          'meta[name="theme-color"]'
        );
        themeColorMetaTag.setAttribute("content", newColor);
        document.body.style.backgroundColor = newColor;
        document.body.style.color =
          newColor === "#ffffff" ? "#000000" : "#ffffff";
      }
      // 初始化主题颜色
      setThemeColor();
    </script>
  </body>
</html>

点击按钮可实现背景和文字颜色的切换。

# window.matchMedia()

  • 定义

matchMedia() 方法返回一个新的 MediaQueryList 对象,表示指定的媒体查询字符串解析后的结果。返回的 MediaQueryList 可被用于判定 Document 是否匹配媒体查询,或者监控一个 document 来判定它匹配了或者停止匹配了此媒体查询。

  • 参数
    • mediaQueryString:一个被用于媒体查询解析的字符串。
  • 示例
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Document</title>
  </head>
  <body>
    <span class="mq-value"></span>
    <script>
      let mql = window.matchMedia("(max-width: 600px)");
      document.querySelector(".mq-value").innerText = mql.matches;
    </script>
  </body>
</html>

# mediaQueryString 规则

# 针对媒体类型

  • 针对打印机
@media print {
  /* … */
}
  • 针对屏幕和打印设备
@media screen, print {
  /* … */
}

# 针对媒体功能

  • 鼠标悬停在元素之上
@media (hover: hover) {
  /* … */
}
  • 横向或纵向
@media print and (orientation: portrait) {
  /* … */
}
  • 最大宽度
@media (max-width: 1250px) {
  /* … */
}

或者可以写成这样

@media (width <= 1250px) {
  /* … */
}
  • <> 的运用
@media (min-width: 30em) and (max-width: 50em) {
  /* … */
}
@media (30em <= width <= 50em) {
  /* … */
}

上面这两个规则等效(需要区别于 JS 的条件判断)

  • 任何具有彩色屏幕的设备
@media (color) {
  /* … */
}

# 创建复杂的媒体查询

  • 宽度至少为 30 em 的横向设备上
@media (min-width: 30em) and (orientation: landscape) {
  /* … */
}

类似的将设备限制为屏幕:

@media screen and (min-width: 30em) and (orientation: landscape) {
  /* … */
}

orientation 包含两个属性:landscape(横向)、portrait(纵向)

  • 设备高度为 680px 或更高,或者浏览器视口处于纵向模式(视口高度大于视口宽度)
@media (min-height: 680px), screen and (orientation: portrait) {
  /* … */
}

逗号分隔查询列表,表示进行多个查询匹配

  • 除印刷媒体之外
@media not print {
  /* … */
}
  • not 只对后面紧接的媒体查询生效,例如
@media not screen and (color), print and (color) {
  /* … */
}

等效于:

@media (not (screen and (color))), print and (color) {
  /* … */
}