在页面刷新时保持切换位置

时间:2021-01-13 00:20:55

标签: javascript html css asp.net-core toggle

我对 HTML/CSS/JS 很陌生……我有一个明/暗模式切换开关,可以在我的 asp.net 核心站点上激活暗模式。一切正常,我使用 localhost 在页面刷新或加载时保存深色/浅色主题。问题是我的拨动开关一直恢复到浅色模式。我尝试了几个选项,但我似乎无法弄清楚需要做什么才能在页面加载时将切换开关保持在正确的位置。

这是我的代码

HTML 复选框:

<div class="toggle-container">
                        <input type="checkbox" id="dark-mode-switch" name="theme" /><label for="dark-mode-switch">Toggle</label>
                    </div>

CSS:

.switch {
    align-self: self-end;
    margin: inherit;
    padding: inherit;
    border-radius: 15px;
    display: grid;
    grid-template-columns: 90px auto;
    grid-template-rows: auto auto;
    grid-template-areas: "title switch" "content content";
}

    .switch h1 {
        margin: auto;
        color: var(--color-headings);
        font-size: 16px;
        line-height: inherit;
    }


input[type=checkbox] {
    height: 0;
    width: 0;
    visibility: hidden;
}

label {
    cursor: pointer;
    text-indent: -9999px;
    width: 52px;
    height: 27px;
    background: grey;
    float: right;
    border-radius: 100px;
    position: relative;
}

    label:after {
        content: '';
        position: absolute;
        top: 3px;
        left: 3px;
        width: 20px;
        height: 20px;
        background: #fff;
        border-radius: 90px;
        transition: 0.4s;
    }

input:checked + label{
    background: var(--color-headings);
}

    input:checked + label:after {
        left: calc(100% - 5px);
        transform: translateX(-100%);
    }

label:active:after {
    width: 45px;
}

html.transition,
html.transition *,
html.transition *:before,
html.transition *:after {
    transition: all 750ms !important;
    transition-delay: 0 !important;

JS

let darkMode = localStorage.getItem('data-theme');
const checkbox = document.querySelector('input[name=theme]');

if (darkMode === 'dark') {
    document.documentElement.setAttribute('data-theme', 'dark')
    localStorage.setItem('data-theme', 'dark')
}

checkbox.addEventListener('change', function () {
    if (this.checked) {
        trans()
        document.documentElement.setAttribute('data-theme', 'dark')
        localStorage.setItem('data-theme', 'dark')
        
    } else {
        trans()
        document.documentElement.setAttribute('data-theme', 'light')
        localStorage.setItem('data-theme', 'light')
    }
})

let trans = () => {
    document.documentElement.classList.add('transition');
    window.setTimeout(() => {
        document.documentElement.classList.remove('transition')
    }, 1000)
}

1 个答案:

答案 0 :(得分:0)

我认为问题在于您没有重新分配复选框的“已选中”属性。您有代码可以根据复选框值更新暗模式,但反过来不行。

解决此问题的一种方法是修改您的 if (darkmode === 'dark') 代码以设置 checkedcheckbox 属性,而不是直接更新 data-theme 和本地存储。这应该有效:

if (darkMode === 'dark') {
    checkbox.checked = true;
}

您还应该重新排列您的 JS 以确保您没有未定义的引用。我个人会这样安排:

const checkbox = document.querySelector('input[name=theme]');

let trans = () => {
    ...
}

checkbox.addEventListener('change', function () {
    ...
})


let darkMode = localStorage.getItem('data-theme');
if (darkMode === 'dark') {
    ...
}

至少,必须在更新 checked 的值之前定义更改事件侦听器,否则从 localstorage 加载时不会触发该事件。

此外,此代码需要位于 HTML 的末尾,或者包含在 domready 事件处理程序中。否则,checkbox 可能未定义,您的代码将无法运行。


更新:我刚刚看到您使用的是 ASP.NET,因此以下内容不适用。但我会把它留在这里以供参考,因为它可能对其他人有所帮助。这是本地存储的一个非常常见的问题。

最后,不会为通过 file:// URL 加载的文件保存 localstorage。如果您将它放在一个文件中并直接加载到 Web 浏览器中(没有服务器),那么每次离开页面时都会重置 localstorage。

相关问题