Каким образом можно осуществить смену темы?

Привет! У меня есть реализованный переключатель тем, который позволяет менять фон с черного на белый и обратно. В целом, все работает корректно, вот стили: <br/><br/> У элемента body есть определенный класс: если он присутствует, применяются одни стили, если его нет — другие. <br/><br/> Однако возникла небольшая проблема: во время начальной отрисовки сайта, пока не появится элемент body, JavaScript не может добавить к нему нужный класс темы. Это приводит к тому, что если я, например, нахожусь на белой теме, на несколько секунд отображается черная тема, так как она установлена по умолчанию в случае отсутствия класса у body. Затем, когда JavaScript срабатывает и класс добавляется, тема меняется на белую. Таким образом, при каждой перезагрузке происходит переключение темы с черной на белую, что создает неприятный визуальный эффект. <br/><br/> Я пытался загрузить JavaScript в самом начале, но это не решает проблему, так как body еще не существует, и класс некуда привязать. <br/><br/> Вот ссылка на сайт: <a href="http://smirno.temp.swtest.ru/" rel="nofollow">smirno.temp.swtest.ru</a> <br/><br/> Вот код JavaScript: <br/><pre><code>function setTheme(themeName) {
            localStorage.setItem('theme', themeName);
            document.body.className = themeName;

            // Переключение лого и текста
            var logoDark = document.querySelectorAll('#logo-dark');
            var logoWhite = document.querySelectorAll('#logo-white');
            var switchTextDark = document.querySelectorAll('#switch__text-dark');
            var switchTextLight = document.querySelectorAll('#switch__text-light');
            
            if (themeName === 'root') {
                logoWhite.forEach(function(logo) {
                    logo.style.display = 'none';
                });
                logoDark.forEach(function(logo) {
                    logo.style.display = 'block';
                });
                switch...
  • 5 ноября 2024 г. 5:53
Ответы на вопрос 2
Чтобы решить проблему с переходом между темами и устранить временное отображение некорректной темы на момент загрузки страницы, вы можете применить несколько методов. Вот несколько шагов, которые помогут вам это сделать:

1. **Сохранение настроек темы в `localStorage`**: Это уже сделано в вашем коде. Проверьте, сохраняется ли тема при переключениях и загружайте ее при старте.

2. **Установка темы при загрузке страницы**: Вы можете использовать JavaScript для установки темы на этапе загрузки страницы. Это можно сделать, добавив соответствующий код в `<head>`, чтобы предотвратить визуальный "мигание" темы.

    Вот пример того, как может выглядеть ваш код:

    ```html
    <script>
        // Установите тему во время загрузки страницы
        document.addEventListener("DOMContentLoaded", function() {
            const theme = localStorage.getItem('theme') || 'root'; // Замените 'root' на 'dark' или 'light' по умолчанию
            document.body.className = theme;
        });
    </script>
    ```

3. **Скрытие содержимого до применения темы**: Можно скрыть содержимое страницы до применения темы с помощью CSS. Например:

    ```css
    body {
        visibility: hidden;
    }
    
    body.theme-loaded {
        visibility: visible;
    }
    ```
    
    Затем добавьте класс `theme-loaded` к `body` после того, как тема будет установлена в скрипте:

    ```javascript
    document.body.className = theme; 
    document.body.classList.add('theme-loaded');
    ```

4. **Переключение темы**: Убедитесь, что ваш скрипт для переключения тем работает корректно и обновляет класс `body` и логотипы.

Пример полного кода для темы:

```html
<!DOCTYPE html>
<html lang="ru">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Смена темы</title>
    <style>
        body {
            visibility: hidden; /* Скрыть содержимое до загрузки темы */
        }
        
        body.theme-loaded {
            visibility: visible; /* Показать содержимое после загрузки темы */
        }

        /* Пример стилей для тем */
        body.root {
            background-color: white;
            color: black;
        }

        body.dark {
            background-color: black;
            color: white;
        }
    </style>
    <script>
        document.addEventListener("DOMContentLoaded", function() {
            const theme = localStorage.getItem('theme') || 'root';
            document.body.className = theme;
            document.body.classList.add('theme-loaded'); // Показать содержимое
        });

        function setTheme(themeName) {
            localStorage.setItem('theme', themeName);
            document.body.className = themeName;
            document.body.classList.add('theme-loaded'); // Показать содержимое при переключении
        }
    </script>
</head>
<body>
    <!-- Ваш контент здесь -->
</body>
</html>
```

Эти изменения помогут устранить визуальное мигание при переключении тем, и пользователи увидят корректно установленную тему сразу после загрузки страницы.
Все что нужно для переключения темы: 

Инициализация при загрузке, максимально короткий скрипт. При желании можно добавить проверку на пользовательские предпочтения prefer-color-theme
<head>
    <script>
        const theme = localStorage.getItem('color-theme') === 'dark' ? 'dark' : 'light';
        document.documentElement.setAttribute('data-color-theme', theme);
    </script>


Код переключателя

document.querySelectorAll('.theme-toggle').forEach(el => {
    el.addEventListener('click', () => {
        const theme = document.documentElement.getAttribute('data-color-theme') === 'dark' ? 'light' : 'dark';
        document.documentElement.setAttribute('data-color-theme', theme);
        localStorage.setItem('color-theme', theme);
    });
});


И стили

:root {
  --body-bg: white;
}
[data-color-theme="dark"] {
  -body-bg: black;
}


Разумеется, вместо атрибута можно вешать класс
document.documentElement.classList.add('dark-theme');
:root {
  --body-bg: white;
}
html.dark-theme {
  -body-bg: black;
}
Похожие вопросы