【问题标题】:Keeping toggle position on page refresh在页面刷新时保持切换位置
【发布时间】:2021-04-17 23:55:11
【问题描述】:

我对 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)
}

【问题讨论】:

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


    【解决方案1】:

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

    解决此问题的一种方法是修改您的if (darkmode === 'dark') 代码以设置checkboxchecked 属性,而不是直接更新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 的值之前定义更改事件侦听器,否则从本地存储加载时不会触发事件。

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


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

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

    【讨论】:

    • 就是这样!有用!我已经在那个确切的位置尝试了 checkbox.checked = true ,但是直到我重新排列了我的 JS 才起作用。我不确定你说它不起作用是什么意思。我的本地存储正在保存选择,我能够退出网络浏览器并保存我的选择。
    • 最后一部分不适用于您的设置,抱歉。我最初错过了您提到 ASP.NET 的地方,并认为您可能会直接从本地 PC 打开一个 .html 文件。当您直接打开文件时(使用以file:// 开头的 url),本地存储被重置。任何其他设置(例如 ASP.NET 服务器)都可以。我很高兴你能成功!
    • 是的,谢谢,有时最简单的更改会产生重大影响。
    猜你喜欢
    • 2020-02-29
    • 1970-01-01
    • 2013-07-12
    • 1970-01-01
    • 2018-12-22
    • 1970-01-01
    • 2022-11-27
    • 2020-11-28
    • 1970-01-01
    相关资源
    最近更新 更多