HTML-код
Для демонстрации темной темы понадобится простой HTML-файл. В раздел head
включены CSS-файл styles.css
и два файла JavaScript: darkmode.js
и project.js
.
Мета-параметры — кодировка, вид экрана и заголовок — упоминаются только для заполнения минимального раздела заголовка.
Кнопка переключения на темную тему — darkmode
— расположена внутри элемента <header>
на тринадцатой строчке.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width,initial-scale=1.0,user-scalable=no">
<title>Darkmode-Switch</title>
<link rel="stylesheet" href="css/styles.css">
<script src="js/darkmode.js" defer></script>
<script src="js/project.js" defer></script>
</head>
<body>
<header>
<button class="darkmode" title="darkmode switch" aria-hidden="true"></button>
</header>
<main></main>
<footer></footer>
</body>
</html>
CSS-код
В таблице стилей определяется тело (body
) в светлом и темном режиме. Также устанавливается дизайн для переключателя темы в статусе lightmode
и darkmode
(имя класса, ответственного за это — active
).
Данный CSS максимально прост.
*{
box-sizing:border-box;
}
body{
font-family:sans-serif;
background-color:#fff;
color:#000;
}
body.darkmode{
background-color:#000;
color:#fff;
}
header .darkmode{
position:absolute;
right:2rem;
top:2rem;
width:4rem;
height:1.5rem;
border-radius:500px;
border:2px solid #888;
background-color:transparent;
cursor:pointer;
appearance:none;
}
header .darkmode::before{
content:'';
position:absolute;
left:4px;
top:50%;
width:1rem;
height:1rem;
background-color:#888;
border-radius:50%;
transform:translateY(-50%);
}
header .darkmode.active::before{
left:auto;
right:4px;
}
Файл project.js
Этот файл используется для инициализации темной темы с помощью функции darkmode_init()
— которая будет описана позже — в событии DOMContentLoaded
.
document.addEventListener('DOMContentLoaded',function()
{
darkmode_init();
});
Файл darkmode.js
В этом примере от начала и до конца описана функция для переноса поведения темной темы. Вот полный сценарий:
function darkmode_init()
{
let darkmodeSwitch = document.querySelector('header .darkmode');
let darkmodeCookie = {
set:function(key,value,time,path,secure=false)
{
let expires = new Date();
expires.setTime(expires.getTime() + time);
var path = (typeof path !== 'undefined') ? pathValue = 'path=' + path + ';' : '';
var secure = (secure) ? ';secure' : '';
document.cookie = key + '=' + value + ';' + path + 'expires=' + expires.toUTCString() + secure;
},
get:function()
{
let keyValue = document.cookie.match('(^|;) ?darkmode=([^;]*)(;|$)');
return keyValue ? keyValue[2] : null;
},
remove:function()
{
document.cookie = 'darkmode=; Max-Age=0; path=/';
}
};
if(darkmodeCookie.get() == 'true')
{
darkmodeSwitch.classList.add('active');
document.body.classList.add('darkmode');
}
darkmodeSwitch.addEventListener('click', (event) => {
event.preventDefault();
event.target.classList.toggle('active');
document.body.classList.toggle('darkmode');
if(document.body.classList.contains('darkmode'))
{
darkmodeCookie.set('darkmode','true',2628000000,'/',false);
}
else
{
darkmodeCookie.remove();
}
});
}
Теперь рассмотрим процесс в четыре простых шага.
Шаг 1. Ссылка на кнопку
Сначала перехватываем переключатель из DOM.
let darkmodeSwitch = document.querySelector('header .darkmode');
Шаг 2. Функциональность файлов cookie
Объект darkmodeCookie
содержит три метода.
set
, чтобы задать файл cookie для темной темы.get
, чтобы прочитать файл cookie, если он существует.remove
, чтобы удалить файл cookie.
let darkmodeCookie = {
set:function(key,value,time,path,secure=false)
{
let expires = new Date();
expires.setTime(expires.getTime() + time);
var path = (typeof path !== 'undefined') ? pathValue = 'path=' + path + ';' : '';
var secure = (secure) ? ';secure' : '';
document.cookie = key + '=' + value + ';' + path + 'expires=' + expires.toUTCString() + secure;
},
get:function()
{
let keyValue = document.cookie.match('(^|;) ?darkmode=([^;]*)(;|$)');
return keyValue ? keyValue[2] : null;
},
remove:function()
{
document.cookie = 'darkmode=; Max-Age=0; path=/';
}
};
Шаг 3. Обработка классов CSS
Метод get
объекта darkmodeCookie
позволяет проверить, существует ли файл cookie для темной темы. Если да, то добавляем класс active
к переключателю и класс darkmode
в тело body
.
if(darkmodeCookie.get() == 'true')
{
darkmodeSwitch.classList.add('active');
document.body.classList.add('darkmode');
}
Шаг 4. Управление переключателем
Эта часть скрипта добавляет прослушиватель событий к переключателю, чтобы была возможность изменять классы как в самом переключателе, так и в теле страницы.
В шестой строке кода проверяем, есть ли у body
класс darkmode
после переключения, которое происходит на четвертой строке. Если это так, устанавливаем файл cookie darkmode
, срок действия которого в этом примере истекает через один месяц (2 628 000 000 миллисекунд).
Последнему параметру darmodeCookie.set()
в восьмой строке должно быть присвоено значение true
, если страница зашифрована по протоколу SSL. Для локального тестирования просто установите туда false
. Второй параметр — это значение, здесь используется просто true
в качестве строки.
Если файл cookie необходимо удалить, поскольку body
не содержит класса darkmode
, применяется darkmodeCookie.remove()
.
darkmodeSwitch.addEventListener('click', (event) => {
event.preventDefault();
event.target.classList.toggle('active');
document.body.classList.toggle('darkmode');
if(document.body.classList.contains('darkmode'))
{
darkmodeCookie.set('darkmode','true',2628000000,'/',false);
}
else
{
darkmodeCookie.remove();
}
});
Заключение
С помощью этих простых шагов вы можете сделать сайт более удобным для пользователя. Для большей гибкости и контроля также можно устанавливать класс darkmode
в body
с помощью PHP, а не JavaScript.
Читайте также:
- Объясняем Z-index: как позиционировать элементы с помощью CSS
- Как сделать темную тему с помощью CSS
- Основы JavaScript: управление DOM элементами (часть 4)
Читайте нас в Telegram, VK и Дзен
Перевод статьи Stephan Romhart: Code a cookie-based darkmode switch in CSS and vanilla JavaScript