是否可以使用JavaScript在页面上切换亮模式和暗模式?

k10s72fa  于 2023-03-16  发布在  Java
关注(0)|答案(1)|浏览(134)

我可以用

@media (prefers-color-scheme: dark)

window.matchMedia('(prefers-color-scheme: dark)').matches

检测操作系统是否处于暗模式。
但是,有没有什么方法可以让我自己用JavaScript修改状态呢?这样,如果用户不想保留操作系统的设置,我就可以创建一个按钮,让他们在黑暗和光明之间切换。

mf98qq94

mf98qq941#

也许支持深色模式最简单的方法是为浅色主题定义文本、背景、边框、阴影等的所有颜色设置,然后使用媒体查询覆盖颜色,但正如您所指出的,这并没有给予您的访问者切换的选项。
为了给予你的访问者一个选择,你可以在你的页面上添加一个小的、不显眼的开关(一些网站,比如GitHub,在桌面版本上显示了一个开关,但是要在移动终端上打开开关,用户必须打开设置功能)。
我所做的是将用户的首选项保存在localStorage中,并在他们下次返回时遵循所存储的首选项(即使他们已经更改了系统设置)。
为了显示暗模式,我在documentElement(html标签)中添加了一个暗模式类。在我的CSS中,我有第二组CSS规则集:

body {
  background-color: #FFFFFF;
  font-family: 'Open Sans', sans-serif;
  color: #212121;
  font-weight: 400;
  line-height: 1.125em;
  height: 100%;
}

.dark-mode body {
  background-color: #121212;
  color: #ffffff;
}

切换颜色的另一个方法是在标签上应用data-color-mode=“dark”属性,并使用CSS变量:

:root {
  --background-color: #f0f0f0;
  --paragraph-color: #333;
}

[data-color-mode="dark"] {
  --background-color: #333;
  --paragraph-color: #ccc;
}

CSS变量在Internet Explorer中不起作用,因此它将恢复为IE的标准颜色。
由于我仍然需要支持IE9和更高版本,我不使用CSS变量选项,因为我使用基于intersectionObserver的惰性加载,我不给予IE用户切换主题的选项-他们自动获得灯光主题。
为了让它工作,我在我的head部分有以下代码:

// IE doesn't get the dark mode option – I use IntersectionObserver as a proxy for IE
if ("IntersectionObserver" in window)  {
    window.dark = JSON.parse(window.localStorage.getItem("theme_mode"));
    if (window.dark === null) { // First time - use prefers color to set the theme
        if (window.matchMedia && window.matchMedia("(prefers-color-scheme: dark)").matches) {
            window.dark = true;
            document.documentElement.className = document.documentElement.classList.add("dark-mode");
        } else {
            window.dark = false;
        }
        localStorage.setItem("theme_mode", JSON.stringify(window.dark));
    } else if (window.dark === true) { // Returning user - prefers dark
        document.documentElement.classList.add("dark-mode");
    } // Returning user - prefers light - window.dark is false
} else { // Browser is IE - hide dark mode stuff
    document.documentElement.classList.add(" ie");
}

IE9不支持classList,但是如果访问者使用IE9,我可以选择加载一个polyfill。
要设置switch函数,我在页面底部有以下代码:

// set the selector switch to the right setting
var modeToggle = document.getElementById("light-dark-toggle");
if (window.dark) {
    modeToggle.checked = true;
} else {
    modeToggle.checked = false;
}

    
modeToggle.addEventListener('change', function() {
    window.dark = modeToggle.checked;
    if (window.dark) {
        document.documentElement.classList.add("dark-mode");
    } else {
        document.documentElement.classList.remove("dark-mode");
    }
    localStorage.setItem("theme_mode", JSON.stringify(window.dark));
    lazyLoad();
});

切换开关会使页面重新加载图像,加载深色图像而不是浅色图像,反之亦然。

相关问题