Не сохраняется сохраненная тема в LocalStorage

Рейтинг: 0Ответов: 3Опубликовано: 24.06.2023

Получается сделать смену темы на клик, но при обновлении страницы заданное значение не выгружается из LocalStorage

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
  <link rel="stylesheet" href="https://cdn.rawgit.com/Chalarangelo/mini.css/v3.0.1/dist/mini-default.min.css">
  <style>
    .page {
      text-align: center;
    }
    .dark {
      background-color: #000;
    }
    .text {
      color: #fff;
    }
  </style>
</head>
<body class="page" id="page">
    <p id="text" >Я текст, меняющий цвет</p>
    <button id="switcher">Темный режим</button>
    <script>
        const page = document.getElementById('page');
        const text = document.getElementById('text');
        const switcher = document.getElementById('switcher');
      
        let theme = '';
        let switcherLightDark = 0;
        let storage = '';
        localStorage.getItem('current', theme);
        switcher.onclick = function (){
          if ( switcherLightDark === 0) {
            switcherLightDark += 1;
            theme = 'dark';
            storage = localStorage.setItem('current', theme);
            page.classList.add('dark');
            text.classList.add('text'); 
            return;
          } 
          if (switcherLightDark === 1) {
            switcherLightDark -= 1;
            theme = 'light';
            storage = localStorage.setItem('current', theme);
            page.classList.remove('dark');
            text.classList.remove('text'); 
            return;
          }
        }
    </script>
</body>
</html>

Ответы

▲ 4

Давайте разберемся, что в вашем коде не так и попытаемся сделать его гораздо лучше?

  1. Куча переменных, которые вы создаете - не имеют смысла. Можно обойтись всего одной.
  2. localStorage.getItem('current', theme); - метод getItem принимает только один параметр.
  3. Вы при загрузке страницы ничего не делаете с "полученными" данными.

А теперь что можно сделать и как улучшить.

  1. Для начала мы убираем все переменные и добавляем только isDarkTheme, она у нас будет булевая (т.е. true/false), и значение при загрузке будет из localStorage.
  2. Сразу после этого мы дадим класс элементам, если наша переменная isDarkTheme равняется true. В данном случае мы можем воспользоваться вторым аргументом метода toggle у classList.
  3. Мы переписали обработчик клика, теперь мы инвертируем значение переменной isDarkTheme, записываем новое значение в localStorage и переключаем классы у элементов.

Могут возникнуть вопросы, а зачем нужны эти JSON преобразования. Отвечу, значение в localStorage может быть только строкой, для этого мы переводим наше булевое значение в строку с помощью JSON.stringify и обратно с помощью JSON.parse.

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
  <link rel="stylesheet" href="https://cdn.rawgit.com/Chalarangelo/mini.css/v3.0.1/dist/mini-default.min.css">
  <style>
    .page {
      text-align: center;
    }
    .dark {
      background-color: #000;
    }
    .text {
      color: #fff;
    }
  </style>
</head>
<body class="page" id="page">
    <p id="text" >Я текст, меняющий цвет</p>
    <button id="switcher">Темный режим</button>
    <script>
        const page = document.getElementById('page');
        const text = document.getElementById('text');
        const switcher = document.getElementById('switcher');
      
        let isDarkTheme = JSON.parse(localStorage.getItem("isDarkTheme"));
        
        page.classList.toggle('dark', isDarkTheme === true);
        text.classList.toggle('text', isDarkTheme === true); 

        switcher.onclick = function (){
          isDarkTheme = !isDarkTheme;
          
          page.classList.toggle('dark', isDarkTheme === true);
          text.classList.toggle('text', isDarkTheme === true); 
          
          localStorage.setItem("isDarkTheme", JSON.stringify(isDarkTheme));
        }
    </script>
</body>
</html>

▲ 0

Ваша проблема в том, что вы получаете данные из localStorage неправильно. Вы пишете:

localStorage.getItem('current', theme);

Но когда мы получаем данные из localStorage с помощью getItem, в скобки нам нужно передавать всего один аргумент, а именно ключ, по которому мы создавали данный localStorage используя localStorage.setItem().

Вам нужно использовать метод localStorage.getItem() правильно для получения значения из хранилища и проверять его наличие. Для решения вашей проблемы я переписал ваш код и объяснил его ниже. Вот исправленный код:

const page = document.getElementById('page');
const text = document.getElementById('text');
const switcher = document.getElementById('switcher');

let theme = localStorage.getItem('current');
if (theme === 'dark') {
  page.classList.add('dark');
  text.classList.add('text');
}

switcher.onclick = function () {
  if (theme === 'dark') {
    theme = 'light';
    localStorage.setItem('current', 'light');
    page.classList.remove('dark');
    text.classList.remove('text');
  } else {
    theme = 'dark';
    localStorage.setItem('current', 'dark');
    page.classList.add('dark');
    text.classList.add('text');
  }
};

Здесь мы получаем значение из LocalStorage в переменную theme и, если оно равно 'dark', применяем соответствующие классы к элементам страницы. Затем при клике на кнопку мы проверяем значение theme и в зависимости от него меняем классы и записываем новое значение в LocalStorage. Теперь при обновлении страницы оно будет выгружаться и применяться к элементам.

▲ -1

let chkbox = document.getElementById('chkbox');
let theme = localStorage.getItem('theme') || '';
document.body.className = theme;
chkbox.checked = theme !== '';
chkbox.addEventListener('change',function(){
  theme = this.checked ? 'dark' : '';
  localStorage.setItem('theme',theme);
  document.body.className = theme;
})
body.dark {
  background: #2d2d2d;
}

.dark .text{
  color: white; 
}
 <label for='chkbox' class='text'>Цветовая схема</label>
<input type='checkbox' id="chkbox">

Альтернатива с использование атрибута theme.

let chkbox = document.getElementById('chkbox');
let theme = localStorage.getItem('theme') || '';
document.body.setAttribute('theme',theme);
chkbox.checked = theme !== '';
chkbox.addEventListener('change',function(){
  theme = this.checked ? 'dark' : '';
  localStorage.setItem('theme',theme);
  document.body.setAttribute('theme',theme);
})
body[theme=dark] {
  background: #2d2d2d;
}

[theme=dark] .text{
  color: white; 
}
 <label for='chkbox' class='text'>Цветовая схема</label>
<input type='checkbox' id="chkbox">