如何使用 JavaScript 检测暗模式?

IT技术 javascript macos-darkmode
2021-02-27 22:58:04

Windows 和 macOS 现在具有深色模式。

对于 CSS,我可以使用:

@media (prefers-dark-interface) { 
  color: white; background: black 
}

但我使用的是 Stripe Elements API,它将颜色放入 JavaScript

例如:

const stripeElementStyles = {
  base: {
    color: COLORS.darkGrey,
    fontFamily: `-apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, "Noto Sans", sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji"`,
    fontSize: '18px',
    fontSmoothing: 'antialiased',
    '::placeholder': {
      color: COLORS.midgrey
    },
    ':-webkit-autofill': {
      color: COLORS.icyWhite
    }
  }
}

如何在 JavaScript 中检测操作系统的首选配色方案?

3个回答
if (window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').matches) {
    // dark mode
}

观察变化:

window.matchMedia('(prefers-color-scheme: dark)').addEventListener('change', e => {
    const newColorScheme = e.matches ? "dark" : "light";
});
请注意,prefers-color-scheme: dark这在 Edge 中似乎不起作用。不在 CSS 或 Javasript 中。
2021-04-25 22:58:04
是的,那是“旧”版本。据我所知,在基于 EdgeHTML 的 Edge 中检测暗模式的唯一方法是通过 Windows API,只有当用户通过 Windows 应用商店“安装”应用程序时才可用。我不会为此烦恼,因为 Windows 功能更新 2004(现在推出)用新的基于 Chromium 的 Edge 替换了“旧”Egde。
2021-04-27 22:58:04
我的版本是Microsoft Edge 44.18362.449.0Microsoft EdgeHTML 18.18363但我发现这是一个旧版本。显然,Windows 更新不会自动更新 Edge...手动更新,现在可以使用了。
2021-04-28 22:58:04
@VDWWD 旧 Edge 还是新 Edge(基于 Chromium)?
2021-05-09 22:58:04
我会在这里离开这个: window.matchMedia('(prefers-color-scheme: dark)').addEventListener('change', function(e) { console.log('changed!!');})
2021-05-15 22:58:04

根据MediaQueryList - Web APIs | MDNaddListener才是听变的正确方式。addEventListener在 iOS 13.4 上对我不起作用。

window.matchMedia('(prefers-color-scheme: dark)').addListener(function (e) {
  console.log(`changed to ${e.matches ? "dark" : "light"} mode`)
});
只是引用提到的MDN,因为我很困惑并addListener()查了一下:“向MediaQueryList添加一个回调,每当媒体查询状态(无论文档是否与列表中的媒体查询匹配)发生变化时都会调用该回调。此方法存在主要是为了向后兼容;如果可能,您应该改为使用addEventListener()来监视更改事件。”
2021-05-02 22:58:04
同样来自 MDN - 这基本上是 EventTarget.addEventListener() 的别名,用于向后兼容。
2021-05-08 22:58:04

您可以直接使用 JavaScript检查 CSS Media-Queries

window.matchMedia() 方法返回一个 MediaQueryList 对象,表示指定的 CSS 媒体查询字符串的结果。matchMedia() 方法的值可以是 CSS @media 规则的任何媒体特性,如 min-height、min-width、orientation 等。

要检查 Media-Query 是否为真,matches可以使用属性

// Check to see if Media-Queries are supported
if (window.matchMedia) {
  // Check if the dark-mode Media-Query matches
  if(window.matchMedia('(prefers-color-scheme: dark)').matches){
    // Dark
  } else {
    // Light
  }
} else {
  // Default (when Media-Queries are not supported)
}

color-scheme根据用户的偏好动态更新,可以使用以下内容:

function setColorScheme(scheme) {
  switch(scheme){
    case 'dark':
      // Dark
      break;
    case 'light':
      // Light
      break;
    default:
      // Default
      break;
  }
}

function getPreferredColorScheme() {
  if (window.matchMedia) {
    if(window.matchMedia('(prefers-color-scheme: dark)').matches){
      return 'dark';
    } else {
      return 'light';
    }
  }
  return 'light';
}

if(window.matchMedia){
  var colorSchemeQuery = window.matchMedia('(prefers-color-scheme: dark)');
  colorSchemeQuery.addEventListener('change', setColorScheme(getPreferredColorScheme()));
}