You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何通过JavaScript获取prefers-contrast等matchMedia查询的当前值?

如何通过JavaScript获取prefers-contrast等matchMedia查询的当前值?

嗨,这个问题问得太到位了!确实,挨个枚举prefers-contrast的所有已知值不仅显得笨拙,而且完全没法应对未来标准的更新——就像你说的,custom就是后来才加入的取值,谁知道以后还会冒出什么新选项呢?而且这个需求其实适用于一大类媒体查询,比如prefers-color-scheme、prefers-reduced-motion这些,确实需要一个更通用、更靠谱的方案。

咱先直接说现状:遗憾的是,目前JavaScript里还没有一个原生API能直接返回任意媒体查询的当前值——比如没法直接调用window.getMediaQueryValue('prefers-contrast')就拿到结果。不过咱可以用两个聪明的办法来实现,其中一个还能完美兼顾未来兼容的需求。

方法一:CSS变量+JavaScript读取(最推荐,未来兼容拉满)

这个思路的核心是让CSS帮我们做媒体查询的匹配,然后用JS读取对应的结果。不管未来标准给媒体查询加了什么新取值,只要CSS支持,我们就能轻松拿到结果,完全不用改JS代码。

步骤1:在CSS中定义对应变量

我们可以在页面的根元素:root上,为每个关心的媒体查询设置默认变量,然后通过@media规则在对应的条件生效时更新变量值:

:root {
  /* 定义默认值 */
  --prefers-contrast: no-preference;
  --prefers-color-scheme: light;
  --prefers-reduced-motion: no-preference;
  --orientation: portrait;
}

/* 为prefers-contrast的所有可能条件更新变量 */
@media (prefers-contrast: more) {
  :root { --prefers-contrast: more; }
}
@media (prefers-contrast: less) {
  :root { --prefers-contrast: less; }
}
@media (prefers-contrast: custom) {
  :root { --prefers-contrast: custom; }
}

/* 为prefers-color-scheme更新变量 */
@media (prefers-color-scheme: dark) {
  :root { --prefers-color-scheme: dark; }
}

/* 为prefers-reduced-motion更新变量 */
@media (prefers-reduced-motion: reduce) {
  :root { --prefers-reduced-motion: reduce; }
}

/* 为orientation更新变量 */
@media (orientation: landscape) {
  :root { --orientation: landscape; }
}

步骤2:用JS读取变量值

写一个简单的工具函数,就能轻松拿到任意媒体查询的当前值:

function getMediaQueryValue(varName) {
  // 读取根元素的计算样式,拿到对应变量值并去除空格
  return getComputedStyle(document.documentElement).getPropertyValue(varName).trim();
}

// 调用示例
const currentContrast = getMediaQueryValue('--prefers-contrast');
const currentColorScheme = getMediaQueryValue('--prefers-color-scheme');
const currentOrientation = getMediaQueryValue('--orientation');

console.log('当前对比度偏好:', currentContrast);

这个方法的优势

  • 未来兼容:如果以后prefers-contrast新增了比如high-contrast这样的取值,你只需要在CSS里加一段对应的@media规则更新变量,JS代码完全不用改。
  • 性能优秀:只需要读取一次计算样式,不用反复调用matchMedia做暴力匹配。
  • 通用性强:适用于所有“单一条件生效”的媒体查询,包括你提到的hover、prefers-reduced-data等场景。

方法二:优化版纯JS检测(适合不想改CSS的场景)

如果不想依赖CSS,我们可以写一个纯JS的工具函数,但这个方法的局限性是没法自动识别未来新增的媒体查询取值,只能处理已知的旧值。不过比起挨个硬编码所有可能值,这个写法更优雅:

function getPrefersValue(mediaType, defaultValue = 'no-preference') {
  // 先检查默认值是否匹配
  if (window.matchMedia(`(${mediaType}: ${defaultValue})`).matches) {
    return defaultValue;
  }

  // 定义已知的非默认取值,可根据需求扩展
  const knownValues = {
    'prefers-contrast': ['more', 'less', 'custom'],
    'prefers-color-scheme': ['dark'],
    'prefers-reduced-motion': ['reduce'],
    'orientation': ['landscape']
  };

  // 检查已知的非默认取值
  if (knownValues[mediaType]) {
    for (const value of knownValues[mediaType]) {
      if (window.matchMedia(`(${mediaType}: ${value})`).matches) {
        return value;
      }
    }
  }

  // 如果都没匹配到,说明是未知的新取值,返回null
  return null;
}

// 调用示例
const currentContrast = getPrefersValue('prefers-contrast');
console.log('当前对比度偏好:', currentContrast);

额外技巧:监听媒体查询变化

不管用哪种方法,如果你需要在用户的偏好设置变化时(比如系统切换了深色模式)实时更新结果,都可以监听MediaQueryList的change事件:

// 以prefers-contrast为例
const contrastQuery = window.matchMedia('(prefers-contrast)');

// 定义变化后的处理逻辑
function handleContrastChange() {
  const newContrast = getMediaQueryValue('--prefers-contrast');
  console.log('对比度偏好已变更为:', newContrast);
}

// 初始调用一次
handleContrastChange();

// 监听变化
contrastQuery.addEventListener('change', handleContrastChange);

内容来源于stack exchange

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.08 03:10:45