Мы рассмотрели, как делать то, о чём и говорили — переключение темы на основе предпочтений ОС или по щелчку кнопки. Всё это замечательно, но не сохраняется, когда пользователь посещает другую страницу сайта или перезагружает текущую.
Нам нужно сохранить выбор пользователя, чтобы он применялся последовательно на всём сайте и при последующих его посещениях. Для этого мы можем сохранить выбор пользователя в localStorage при переключении темы. Также для этой цели хорошо подходят файлы cookie.
Рассмотрим оба подхода.
Использование localStorage
У нас есть скрипт, который сохраняет выбранную тему в localStorage при её переключении. Другими словами, когда страница перезагружается, скрипт получает выбор из localStorage и применяет его. JavaScript как правило выполняется после CSS, поэтому при таком подходе часто возникает «мерцание неправильной темы».
// Выбираем кнопку
const btn = document.querySelector(".btn-toggle");
// Выбираем настройки темы из localStorage
const currentTheme = localStorage.getItem("theme");
// Если текущая тема в localStorage равна "dark"…
if (currentTheme == "dark") {
// …тогда мы используем класс .dark-theme
document.body.classList.add("dark-theme");
}
// Отслеживаем щелчок по кнопке
btn.addEventListener("click", function() {
// Переключаем класс .dark-theme при каждом щелчке
document.body.classList.toggle("dark-theme");
// Допустим, тема светлая
let theme = "light";
// Если <body> содержит класс .dark-theme…
if (document.body.classList.contains("dark-theme")) {
// …тогда делаем тему тёмной
theme = "dark";
}
// После чего сохраняем выбор в localStorage
localStorage.setItem("theme", theme);
});
Использование файлов cookie через PHP
Чтобы избежать мерцания неправильной темы, мы можем использовать серверный скрипт, например PHP. Вместо сохранения настроек темы пользователя в localStorage, создадим файл cookie через JavaScript и сохраним его. Опять же, это возможно только, если вы уже работали с серверным языком.
// Выбираем кнопку
const btn = document.querySelector(".btn-toggle");
// Отслеживаем щелчок по кнопке
btn.addEventListener("click", function() {
// Переключаем класс .dark-theme у <body>
document.body.classList.toggle("dark-theme");
// Допустим, тема светлая
let theme = "light";
// Если <body> содержит класс .dark-theme…
if (document.body.classList.contains("dark-theme")) {
// …тогда делаем тему тёмной
theme = "dark";
}
// После чего сохраняем выбор в файле cookie
document.cookie = "theme=" + theme;
});
Теперь мы можем проверить существование этого файла cookie и загрузить соответствующую тему, применив подходящий класс к тегу <body>.
<?php
$themeClass = '';
if (!empty($_COOKIE['theme']) && $_COOKIE['theme'] == 'dark') {
$themeClass = 'dark-theme';
}
?>
<!DOCTYPE html>
<html lang="ru">
<!-- и т.д. -->
<body class="<?php echo $themeClass; ?>">
<!-- и т.д. -->
</body>
</html>
Вот как это сделать, используя метод с разными таблицами стилей.
<?php
$themeStyleSheet = 'light-theme.css';
if (!empty($_COOKIE['theme']) && $_COOKIE['theme'] == 'dark') {
$themeStyleSheet = 'dark-theme.css';
}
?>
<!DOCTYPE html>
<html lang="ru">
<head>
<!-- и т.д. -->
<link href="<?php echo $themeStyleSheet; ?>" rel="stylesheet" id="theme-link">
</head>
<!-- и т.д. -->
Если на вашем сайте есть учётные записи пользователей, к примеру, место для входа на сайт и управления профилями — это тоже отличное место для сохранения настроек темы. Отправьте их в базу данных, где хранятся параметры учётной записи пользователя. Затем, когда пользователь залогинится на сайте, выберите тему из базы данных и примените её к странице с помощью PHP (или любого другого серверного скрипта).
Это можно сделать разными способами. В данном примере я беру настройки темы пользователя из базы данных и сохраняю их в переменной сессии во время входа.
<?php
// Получен логин
if (!empty($_POST['login'])) {
// и т.д.
// Если пользователь аутентифицирован…
if ($loginSuccess) {
// …сохраняем его предпочтения темы в переменной сессии
$_SESSION['user_theme'] = $userData['theme'];
}
}
// Сначала берём переменную сессии, если она установлена; в противном случае выбираем cookie
$themeChoice = $_SESSION['user_theme'] ?? $_COOKIE['theme'] ?? null;
$themeClass = '';
if ($themeChoice == 'dark') {
$themeClass = 'dark-theme';
}
?>
<!DOCTYPE html>
<html lang="ru">
<!-- и т.д. -->
<body class="<?php echo $themeClass; ?>">
<!-- и т.д. -->
</body>
</html>
Я использую оператор объединения с null (??), чтобы PHP решил, откуда брать предпочтение темы: из сессии или из файла cookie. Если пользователь залогинился, вместо файла cookie берётся значение переменной сессии. А если пользователь не логинился или разлогинился, то берётся значение cookie.