Як визначити темний режим за допомогою JavaScript?


91

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?



2
Ця друга відповідь не позначена як прийнята, але охоплює те, як користуватися JavaScript разомwindow.matchMedia
mikemaccana

Я не зміг змусити @media (prefers-dark-interface)медіа-запит працювати в Chrome 80 (як ви вже згадували), але @media (prefers-color-scheme: dark)зробив.
Talk Nerdy To Me

Відповіді:


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

2
Зауважте, що це працює лише тоді, коли ви насправді виконуєте код, але не автоматично, коли користувач змінює режим вручну або він автоматично змінюється системою.
Даніель

1
@Daniel Досить очевидно, оскільки це не здається подією, а лише властивістю віконного об'єкта.
Мухаммед бін Юсрат

33
Я просто залишу це тут:window.matchMedia('(prefers-color-scheme: dark)').addEventListener('change', function(e) { console.log('changed!!');})
Jaromanda X

Зверніть увагу, що prefers-color-scheme: dark, здається, не працює в Edge. Не в CSS або Javasript.
VDWWD

@VDWWD старий або новий край (на основі хрому)?
Марк Сабо

10

Відповідно до 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`)
});

1
Також з MDN - це, в основному, псевдонім для EventTarget.addEventListener (), для цілей зворотної сумісності.
Gerrit0,

7

Ви можете перевірити медіа-запити CSS безпосередньо за допомогою Javascript

Метод window.matchMedia () повертає об'єкт MediaQueryList, що представляє результати зазначеного рядка запиту CSS-медіа. Значення методу matchMedia () може бути будь-якою медіа-характеристикою правила CSS @media, наприклад, мінімальна висота, мінімальна ширина, орієнтація тощо.

Щоб перевірити, чи є медіа-запит істинним, 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()));
}
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.