首页 > 解决方案 > 如何将项目添加到 localStorage JS?

问题描述

我有一个功能可以在单击时设置网站的颜色主题,但是当我重新加载页面或转到新页面时,它会恢复为默认主题。我的一行代码应该从 localStorage 获取以前的主题并将其应用于新主题,但我认为它为什么不起作用是因为实际上没有任何代码可以将主题保存到 Storage。要么,要么 localStorage 在页面重新加载/更改时重置。无论哪种方式,我都不确定如何解决它。

这是我的代码:

<a class="switch-light-purple color-palette" id="color-palette" onclick="setTheme('theme-light-purple')">
<script>
  // function to set a given theme/color-scheme
  function setTheme(themeName) {
    localStorage.setItem('theme', themeName);
    document.documentElement.className = themeName;
  }

  // Immediately invoked function to set the theme on initial load
  (function () {
    if (localStorage.getItem('theme') === 'theme-light-purple') {
      setTheme('theme-light-purple');
    }
  })();
</script>
</a>

<a class="switch-dark-blue color-palette" id="color-palette" onclick="setTheme('theme-dark-blue')">
<script>
  // function to set a given theme/color-scheme
  function setTheme(themeName) {
    localStorage.setItem('theme', themeName);
    document.documentElement.className = themeName;
  }

  // Immediately invoked function to set the theme on initial load
  (function () {
    if (localStorage.getItem('theme') === 'theme-dark-blue') {
      setTheme('theme-dark-blue');
    }
  })();
</script>
</a>

标签: javascriptlocal-storage

解决方案


关注点分离:

始终将您的 html、css 和 js 保存在各自的文件中,没有替代品。

所以你index.html应该看起来像这样(假设index.html,style.cssmain.js都在同一个文件夹中)。

<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Document</title>
    <link rel="stylesheet" href="style.css" />
  </head>
  <body>
    <div class="parent-container">
      <a data-theme="theme-dark-blue" class="switch-dark-blue color-palette" id="color-palette">Dark Blue </a>
      <a data-theme="theme-light-purple" class="switch-light-purple color-palette" id="color-palette2">Light Purple</a>
    </div>
    <script src="main.js"></script>
  </body>
</html>

您的 CSS 将位于一个名为 的文件中style.css

还有你的 JS,

// This waits for the DOM to complete loading
document.addEventListener('DOMContentLoaded', function() {
  // all your code goes inside this.
});

此外,正如@Sebastian Simon 在评论中指出的那样,

在 HTML 中重复相同的 id 是无效的。不推荐使用像 onclick 这样的内联事件处理程序。它们是一种过时、难以维护且不直观的事件记录方式。始终使用 addEventListener 代替。

唯一 ID

例如,您可以将id其中一个锚标记更改color-palette2为,但由于您有很多不同的主题,您可以选择更不言自明的名称。但是,只要您id的 s 是唯一的(每页 1 个唯一 id),就可以了。

事件监听器

用于.addEventListener向 DOM 节点添加事件。我已经在我分享的代码片段中完成了这项工作。一旦你习惯了,这很容易。

我还使用数据属性以更“动态”的方式将您的主题传递给您的逻辑。StackOverflow 片段不支持 localStorage,因此我已经注释掉了该行。

function setTheme() {
  let theme;
  let savedTheme = localStorage.getItem('theme')
  
  // check if localstorage already has a theme defined
  // if it has, then set theme variable to it
  // otherwise, get the theme from the data-theme attribute
  // of the current anchor tag clicked represented by this.
  theme = savedTheme || this.dataset.theme
  
  let div = document.querySelector('div.parent-container')
  
  // I'm adding this to a div
  // you can add it to the body tag.
  div.classList.add(theme)
  
  
  // this code can be better but the idea is 
  // to remove all other themes and keep only the intended one.
  if (theme === 'theme-dark-blue') {
    div.classList.remove('theme-light-purple')
  } else {
    div.classList.remove('theme-dark-blue')
  }
  
  console.log(`Set theme to ${theme}`)
}

let palettes = document.querySelectorAll('.color-palette')
palettes.forEach(function(p) {
  p.addEventListener('click', setTheme)
})
a {
  cursor: pointer;
  text-decoration: underline;
  color: blue;
}

.switch-light-purple {
  color: purple;
  margin: 0 15px;
}
<div class="parent-container">
  <a data-theme="theme-dark-blue" class="switch-dark-blue color-palette" id="color-palette">Dark Blue </a>

  <a data-theme="theme-light-purple" class="switch-light-purple color-palette" id="color-palette2">Light Purple</a>
</div>

PS:由于 StackOverflow 不支持 localStorage,因此代码段将不起作用。


推荐阅读