Как написать переключатель темы на базе файлов cookie с помощью CSS и ванильного JavaScript

Как написать переключатель темы на базе файлов cookie с помощью CSS и ванильного JavaScript

https://t.me/javascriptv

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');

Объект 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.



Report Page