Как определить темный режим с помощью JavaScript?

В Windows и macOS теперь есть темный режим.

Для CSS я могу использовать:

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

Но я использую API Stripe Elements, который помещает цвета в 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?


person mikemaccana    schedule 31.05.2019    source источник
comment
Возможный дубликат Как определить, включен ли темный режим в macOS Mojave на моем веб-сайте?   -  person mikemaccana    schedule 31.05.2019
comment
В эту секунду ответ не помечен как принятый, но описывает, как использовать JavaScript с window.matchMedia   -  person mikemaccana    schedule 31.05.2019
comment
Мне не удалось заставить @media (prefers-dark-interface) медиа-запрос работать в Chrome 80 (как вы упомянули), но @media (prefers-color-scheme: dark) сделал.   -  person Talk Nerdy To Me    schedule 01.04.2020


Ответы (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";
});
person Mark Szabo    schedule 04.09.2019
comment
Обратите внимание, что это работает только тогда, когда вы действительно выполняете код, но не автоматически, когда пользователь изменяет режим вручную или он автоматически изменяется системой. - person Daniel; 29.01.2020
comment
@Daniel Довольно очевидно, поскольку это не похоже на событие, а просто свойство объекта окна. - person Muhammad bin Yusrat; 20.02.2020
comment
Я просто оставлю это здесь: window.matchMedia('(prefers-color-scheme: dark)').addEventListener('change', function(e) { console.log('changed!!');}) - person Jaromanda X; 06.03.2020
comment
Обратите внимание, что prefers-color-scheme: dark, похоже, не работает в Edge. Ни в CSS, ни в Javasript. - person VDWWD; 07.06.2020
comment
@VDWWD старый Edge или новый Edge (на основе Chromium)? - person Mark Szabo; 07.06.2020
comment
У меня версия Microsoft Edge 44.18362.449.0 с Microsoft EdgeHTML 18.18363. Но я узнал, что это старая версия. Видимо Центр обновления Windows не обновляет автоматически Edge ... Обновился вручную и теперь работает. - person VDWWD; 07.06.2020
comment
Да, это старая версия. Насколько мне известно, единственный способ обнаружить темный режим в Edge на основе EdgeHTML - это через API Windows, которые доступны только в том случае, если пользователь устанавливает приложение через Магазин Windows. Я бы не стал беспокоиться об этом, поскольку обновление функций Windows 2004 (развертывается прямо сейчас) заменяет старый Egde новым Edge на основе Chromium. - person Mark Szabo; 07.06.2020
comment
Этот код не работает в мобильном браузере Xiaomi по умолчанию (браузер Mi), но работает в браузере Chrome, пожалуйста, помогите - person Jafaruddeen Ansari; 11.06.2020
comment
@JafaruddeenAnsari, похоже, браузер Xioami не поддерживает этот стандартный API браузера. Скорее всего, вы ничего не можете сделать. Возможно, у Xiaomi есть нестандартный проприетарный API, но я в этом сомневаюсь. - person Mark Szabo; 12.06.2020
comment
Просто протестируйте Chrome 86.0.4240.75 и Win 10 1909 и работает отлично $ - person RZ87; 12.10.2020

Согласно MediaQueryList - веб-API | MDN, addListener - это правильный способ прислушаться к изменениям. addEventListener у меня не работает на iOS 13.4.

window.matchMedia('(prefers-color-scheme: dark)').addListener(function (e) {
  console.log(`changed to ${e.matches ? "dark" : "light"} mode`)
});
person imgg    schedule 21.04.2020
comment
Также из MDN - это в основном псевдоним для EventTarget.addEventListener () для целей обратной совместимости. - person Gerrit0; 22.06.2020
comment
Просто процитирую упомянутый MDN, поскольку я был сбит с толку и нашел его: addListener() Добавляет в MediaQueryList обратный вызов, который вызывается всякий раз, когда статус медиа-запроса - независимо от того, соответствует ли документ медиа-запросам в списке - изменяется. Этот метод существует прежде всего для обратной совместимости; по возможности вместо этого следует использовать addEventListener() для отслеживания события изменения. - person BananaAcid; 10.04.2021

Вы можете проверить медиа-запросы CSS прямо с помощью Javascript.

Метод window.matchMedia () возвращает объект MediaQueryList, представляющий результаты указанной строки медиа-запроса CSS. Значением метода matchMedia () может быть любая из медиа-функций правила CSS @media, например минимальная высота, минимальная ширина, ориентация и т. Д.

Чтобы проверить, истинен ли 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)
}

Для динамического обновления цветовой схемы, если пользователь изменит свои предпочтения, можно использовать следующее:

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()));
}
person SanBen    schedule 01.04.2020