如何使用JavaScript检测暗模式?


77

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中检测操作系统的首选配色方案?



2
第二个答案未标记为已接受,但涵盖了如何与window.matchMedia
-mikemaccana

我无法使@media (prefers-dark-interface)媒体查询在Chrome 80中正常工作(就像您提到的那样),但是@media (prefers-color-scheme: dark)做到了。
21:08对我说话

Answers:


157
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";
});

1
请注意,这仅在您实际执行代码时有效,而在用户手动更改模式或由系统自动更改模式时则无法自动运行。
丹尼尔

1
@Daniel很明显,因为它似乎不是事件,而只是窗口对象的一个​​属性。
Muhammad bin Yusrat

31
我将在这里离开:window.matchMedia('(prefers-color-scheme: dark)').addEventListener('change', function(e) { console.log('changed!!');})
Jaromanda X

请注意,prefers-color-scheme: dark这似乎在Edge中不起作用。不在CSS或Javasript中。
VDWWD

@VDWWD旧Edge或新Edge(基于铬)?
Mark Szabo

8

根据MediaQueryList-Web API | MDNaddListener是听变化的正确方法。addEventListener在iOS 13.4上不适用于我。

window.matchMedia('(prefers-color-scheme: dark)').addListener(function (e) {
  console.log(`changed to ${e.matches ? "dark" : "light"} mode`)
});

1
同样来自MDN-出于向后兼容的目的,这基本上是EventTarget.addEventListener()的别名。
Gerrit0

7

您可以直接使用Javascript查看CSS Media-Queries

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

要检查Media-Query是否为true,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)
}

要在用户更改偏好时动态更新颜色方案,可以使用以下方法:

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(getPreferedColorScheme()));
}
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.