首页 > 解决方案 > 检查本地存储时,暗模式复选框卡住

问题描述

我正在创建一个暗模式布局,除了一个我似乎找不到的小错误外,我一切正常。我的黑暗模式正在检查一些事情:

  1. 检查以查看系统设置 (OS)
  2. 检查是否有本地存储
  3. 监听点击事件——点击时,反转布局,并保存到本地存储。

问题:

当应用暗模式并且用户刷新页面时,暗模式仍然存在,它正在工作。但是,该复选框不会取消选中。localstorage 键值对更改为“light”,因此可以正常工作。有什么东西破坏了我的复选框,或者让它保持打开状态checkbox.checked = true

JavaScript:

const darkMode = () => {
  const page = document.querySelector("#page");
  const systemDarkMode = window.matchMedia("(prefers-color-scheme: dark)");
  const checkbox = document.querySelector("#dark-mode-select");
  const label = document.querySelector("#dark-mode-label");
  let theme = window.localStorage.getItem("theme");
  let preference; //initialize variable

//Find the system preference of the OS:
  const findSystemPreference = () => {
    if (systemDarkMode.matches) {
      preference = "dark";
    } else {
      preference = "light";
    }
    setTheme(preference);
  };


//Listen for click event, and if checkbox is true, set dark appearance & local storage:
  const setUserPreference = (e) => {

    if (e.target.checked == true) {
      preference = "dark";
      window.localStorage.setItem("theme", "dark");
    } else if (e.target.checked == false) {
      preference = "light";
      window.localStorage.setItem("theme", "light");
    }
    setTheme(preference);
  };

//Set theme: I believe my bug lies somewhere in here. Goal is to check if the preference variable is dark or light, OR is there's a localStorage theme
  const setTheme = (pref) => {
    if (pref === "dark" || theme === "dark") {
      checkbox.checked = true;
      page.classList.add("dark-mode");
      label.textContent = "Dark Mode Is On";
    } else {
      page.classList.remove("dark-mode");
      label.textContent = "Dark Mode Is Off";
      checkbox.checked = false;
    }
  };

  checkbox.addEventListener("click", setUserPreference);
  window.addEventListener("DOMContentLoaded", findSystemPreference);
};

我尝试添加更具体的逻辑,例如添加 `else if (pref === "light" || theme === "dark"),但这仍然不起作用。

代码笔:

演示

编辑:

我可以将检查语句分解为单独的函数,如下所示:

const check = () => {
    checkbox.checked = true;
    page.classList.add("dark-mode");
    label.textContent = "Dark Mode Is On";
  };
  const uncheck = () => {
    page.classList.remove("dark-mode");
    label.textContent = "Dark Mode Is Off";
    checkbox.checked = false;
  };

结合:


  const findSystemPreference = () => {
    if (systemDarkMode.matches) {
      preference = "dark";
      check();
    } else {
      preference = "light";
      uncheck();
    }
  };

但我不知道将if(theme === "dark")语句放在不会破坏我的复选框的位置

标签: javascript

解决方案


错误在这里

if (pref === "dark" || theme === "dark") {

您的theme变量始终设置为,dark因为它从 中检索了该值localStorage,我认为它应该都可以删除theme === "dark"

编辑:您应该从 if 语句和所有内容中删除该条件,创建一个包含该 if 条件功能的函数

const setCheckboxChecked = () => { // change name and you can even abstract this function to use to set the checkbox to true/false, update text, etc.
    checkbox.checked = true;
    page.classList.add("dark-mode");
    label.textContent = "Dark Mode Is On";
}

并且此功能应替换为:

const findSystemPreference = () => {
    if (systemDarkMode.matches) {
      preference = "dark";
    } else {
      preference = "light";
    }
    setCheckboxChecked()
  };

我要做的是仅将复选框设置为 true 一次,然后从 if 中删除该条件,因为theme始终是相同的值,因此始终解析为truefalse

编辑:Codepen 修改


推荐阅读