Мой Javascript код не может определить светлый/темный режим в Chrome.

Вопрос или проблема

Версия Chrome: Версия 130.0.6723.117 (Официальная сборка) (arm64)

Версия Mac OS: Sequoia версия 15.1 (Apple Silicon)

Я хотел бы иметь возможность определять режим светлой/темной темы в Chrome, как это установлено в настройках Chrome. Я могу представить ситуацию, когда пользователь установил настройки внешнего вида Mac OS на светлый режим, а режим внешнего вида Chrome — на темный (или наоборот). В этой ситуации я хотел бы стилизовать свою страницу в соответствии с настройками Chrome.

Однако я не могу определить режим внешнего вида Chrome пользователя, используя подход window.matchMedia.

Вот мой код, встроенный в HTML-файл:

<html>
  <head>
    <script language="javascript">
      const darkModeQuery = window.matchMedia('(prefers-color-scheme: dark)');

      const isDarkMode = () => {
        return darkModeQuery.matches;
      }

      const toggleDarkMode = (isDarkMode) => {
        if (isDarkMode) {
          console.log("Мы в темном режиме");
        } else {
          console.log("Мы в светлом режиме");
        }
      }

      toggleDarkMode(isDarkMode());

      darkModeQuery.addEventListener('change', (event) => {
        console.log("Обнаружено изменение режима");
        toggleDarkMode(event.matches);
      });
    </script>
  </head>
  <body>
    <h1>Тест</h1>
  </body>
</html>

Когда я перехожу в настройки Mac OS и переключаюсь между светлым и темным режимами, мой слушатель событий срабатывает, и в консоль выводится правильное сообщение:
Настройка внешнего вида Mac OS

Однако, когда я перехожу в настройки Chrome и переключаюсь между светлым и темным режимами, слушатель событий не срабатывает:
Настройки Chrome. Кроме того, функция isDarkMode всегда возвращает настройки внешнего вида Mac OS, а не настройки режима Chrome.

Этот ответ на StackOverflow.com предполагает, что приведенный выше код должен по крайней мере быть в состоянии определить режим браузера.

Если подход window.matchMedia не предназначен для определения режима браузера, есть ли другой способ определить режим браузера?

Когда я ставлю точку останова в коде в темном режиме браузера, я вижу, что значение darkModeQuery следующее: Подсказка отладчика, где darkModeQuery.matches равно false. Я ожидал бы, что это будет true.

Я пробовал обслуживать этот файл с локального веб-сервера (например, python -m http.server) и просто открывать его из Finder с теми же результатами.

Я прочитал документацию MDN, попробовал предложенный код Gemini и полдюжины вопросов на stackoverflow.com, но ни одно из решений не работает для меня. Может быть, есть какой-то другой фактор, влияющий на это?

Спасибо!

Ответ или решение

Ваш вопрос о том, как правильно определить режим светлой или темной темы в Google Chrome на macOS, очень актуален и требует более глубокого анализа.

Проблема с определением режима

Судя по вашему описанию, вы уже использовали window.matchMedia('(prefers-color-scheme: dark)'), что является правильным подходом для определения предпочтений пользователя по цветовой схеме, особенно с точки зрения системных настроек. Тем не менее, текущая реализация не позволяет вам определить режим, который установлен именно в Chrome, в отличие от системных настроек macOS.

  1. prefers-color-scheme: Этот медиа-запрос действительно основывается на предпочтениях системы, а не браузера. Это объясняет, почему при изменении режима в настройках macOS вы видите изменения в JavaScript, но если Chrome настроен отдельно на другой режим, то window.matchMedia не будет на это реагировать.

Отсутствие поддержки браузера

На данный момент, К сожалению, для определения режима оформления в Chrome через JavaScript нет стандартного метода, так как prefers-color-scheme в JavaScript привязан к системным настройкам. Chrome просто не предоставляет API, который бы позволял вам отслеживать изменения в собственных настройках.

Возможное решение

Если настоящая необходимость заключается в написании кросс-браузерного решения, вы могли бы использовать подход с CSS-классами, который вы будете менять в зависимости от выбора пользователя. В этом случае, вы можете реализовать переключение тем, которое будет более явно задействовать как системные, так и пользовательские настройки.

document.addEventListener('DOMContentLoaded', (event) => {
  const toggleDarkMode = (isDarkMode) => {
    if (isDarkMode) {
      document.body.classList.add('dark-mode');
    } else {
      document.body.classList.remove('dark-mode');
    }
  };

  const darkModeQuery = window.matchMedia('(prefers-color-scheme: dark)');

  toggleDarkMode(darkModeQuery.matches);

  darkModeQuery.addEventListener('change', (event) => {
    toggleDarkMode(event.matches);
  });

  // Дополнительный код для ручного переключения
  const userPreferenceToggle = document.getElementById('toggle-theme');
  userPreferenceToggle.addEventListener('click', () => {
    const isDarkMode = document.body.classList.contains('dark-mode');
    toggleDarkMode(!isDarkMode);
  });
});

Заключение

Текущая реализация window.matchMedia позволяет вам только взаимодействовать с системными настройками. Для полной адаптации под браузерные настройки, вам придется использовать CSS-классы и, возможно, сохранить предпочтения пользователя в localStorage или в куках, чтобы они сохранялись при перезагрузке страницы.

Широкое использование методов, связанных с изменением тем, требует детального подхода при проектировании интерфейсов пользователя. Не забудьте протестировать свое решение в разных браузерах и версиях, чтобы убедиться в совместимости и правильной работе кода. Это будет способствовать улучшению опыта пользователей на вашем сайте.

Оцените материал
Добавить комментарий

Капча загружается...