如何在网站上添加暗模式切换。

2025-06-08

如何在网站上添加暗模式切换。

我认为每个网站都应该有一个“暗黑模式”的开关。
作为开发者,我们大多数时间都在屏幕前工作,因此,网站上有一个暗黑主题选项可以减少长时间使用(尤其是在夜间)时的眼睛疲劳。

那么,让我们看看如何使用HTMLCSSVanilla JavaScript向网站添加暗主题切换。

在这里,我们还将使用浏览器的本地存储来保存开发者的首选状态。这意味着无论页面重新加载甚至关闭多少次,浏览器都会自动将主题切换为开发者之前的首选状态。

以下是浏览器本地存储的样子。

本地1

在开始之前,我们先来讨论一下本地存储的一些知识。本地存储基本上将数据存储为键值对,并且值只能是字符串。所以,即使你想存储一个对象,也需要将其转换为字符串。

这是另一个示例,您将能够看到键值对。

本地2

目前我们只有一个字符串值,因此我们不需要担心转换。

我们要创建的网站将很少使用 HTML 和 CSS。

以下是不同主题状态下的网站预览。

光

黑暗的

HTML body 标签如下。

<div class="container">
        <!-- header -->
        <header>
            <h1>Logo</h1>
            <div id="right_data">
                <ul>
                    <li>Home</li>
                    <li>projects</li>
                    <li>Blogs</li>
                </ul>
                <img src="./moon.png" id="switcher">
            </div>
        </header>

        <!-- section data -->
        <section>
            <h1>Dark Theme Swicther.</h1>
            <p>Lorem ipsum dolor sit amet consectetur adipisicing. Neque,psam mollitia! Porro magnam earum corporis amet vero maiores in perspiciatis consectetur d</p>
        </section>

        <!-- footer -->
        <footer>
            <p>Lets Connect</p>
            <ul id="social">
                <li>Twitter</li>
                <li>LinkedIn</li>
                <li>Github</li>
            </ul>
        </footer>
    </div>
Enter fullscreen mode Exit fullscreen mode

在上面的 HTML 中,我们所做的就是创建一个带有页眉、页脚和包含一些数据的部分的静态页面。

带有id="switcher"和源的img标签是使用 JavaScript 进行主题切换的标签。

现在,让我们看看 CSS。


*{
    box-sizing: border-box;
    margin: 0;
    padding: 0;
}
:root{
    --primary-color:#fff;
    --secondary-color:#000;
}
.dark_mode{
    --primary-color:#000;
    --secondary-color:#fff;
}
body{
    background: var(--primary-color);
    color: var(--secondary-color);
    text-align: center;
}
.container{
    margin: auto;
    max-width: 700px;
    display: flex;
    justify-content: space-between;
    flex-direction: column;
    align-items: center;
    height: 100vh;
    padding: 20px;
}
h1,h2,p{
    padding: 10px 20px;
}
li{
    cursor: pointer;
    list-style: none;
    margin-right: 15px;
}
img,svg{
    width: 30px;
    cursor: pointer;
}
header{
    height: 60px;
    width: 100%;
    display: flex;
    justify-content:space-between;
    align-items: center;
    text-align: center;
}
header ul{
    display: flex;
}
#right_data{
    display: flex;
    justify-content: space-between;
    align-items: center;
    margin-left: 10px;
}
footer{
    width: 100%;
    display: flex;
    flex-direction: column;
    justify-content:space-between;
    align-items: center;
}
footer ul{
    display: flex;
}
Enter fullscreen mode Exit fullscreen mode

有两点需要注意。其一是:root,它是 CSS 伪类,它与文档的根元素(在本例中是 HTML)匹配。

在:root我们声明了我们想要在网站上使用的颜色,这样做的好处是,改变:root中的颜色值将影响整个主体,这意味着如果我们决定更改网站颜色,我们不需要转到每一行并更改颜色。

下面是一个示例,我所做的只是遵循 CSS。

:root{
    --primary-color:orange;
    --secondary-color:rgb(20, 20, 20);
}
Enter fullscreen mode Exit fullscreen mode

替代文本

另一个是CSS 中的.dark_theme,我们将使用 JavaScript 将其添加到我们的 HTML 主体中,以便仅通过单击即可更改颜色。

现在,转到重要的部分,JavaScript

第一步是选择 id 为id="switcher" 的图像并将其传递给变量,然后我们需要为其添加事件监听器

让变量成为theme_switcher

事件监听器,顾名思义,基本上会监听诸如点击更改提交鼠标悬停等事件。

我们需要一个点击处理程序,当点击时我们需要做一些事情。现在让我们在控制台中打印“clicked”。


//selecting *img* of *id="switcher"* from DOM.
let theme_switcher=document.querySelector("#switcher")
//adding event listener to it
theme_switcher.addEventListener("click",()=>{
        console.log("clicked");
})
Enter fullscreen mode Exit fullscreen mode

点击

正如您上面看到的,现在控制台显示已点击。

但我们想要的是正确更改主题,同时我们还需要更改切换(即月亮图标到太阳图标)的外观。

因此,深色主题将有太阳图标,而浅色主题将有月亮图标。

因此,当触发点击事件时,我们需要将.dark_theme类添加到body标签,以便--primary- 和 --secondary 颜色变量值发生变化。

要向主体添加一个类,下面是代码。

文档.body.classList.添加(“dark_mode”)

我们还可以使用document.body.classList.toggle("dark_mode")
它可以切换 body 标签上的类,但现在让我们继续使用.add

现在,如果我们添加,我们也需要删除它,对吗?为此,我们使用下面的代码行。

document.body.classList.remove(“dark_mode”).

这是body标签在浅色主题下的样子

LT

这是body标签在深色主题下的样子。

替代文本

也可以看到图标上的差异。

但是我们怎样才能做到这一点呢?

还记得我们上面声明的变量theme_switcher吗?在 DOM 上,它本质上就是一个带有 id切换器的图片标签,对吧?没错。

我们将更改img标签的来源。该怎么做?代码如下。

theme_switcher.setAttribute("src","./moon.png")

注意里面的路径或src。它显示 moon.png,而 HTML 里显示的是 sun.png。这基本上就是所谓的“更改源”。

setAttribute基本上设置,或者更准确地说,当我们点击切换器时,将img标签的src属性更改为另一个图像路径。

现在让我们看一下 JavaScript 代码。

let theme_switcher=document.querySelector("#switcher")

theme_switcher.addEventListener("click",()=>{
    if(document.body.classList.contains("dark_mode")){

        document.body.classList.remove("dark_mode")
        theme_switcher.setAttribute("src","./moon.png")
    }else{

        document.body.classList.add("dark_mode")
        theme_switcher.setAttribute("src","./sun.png")
    }
})

Enter fullscreen mode Exit fullscreen mode

因此,我们在这里所做的就是告诉 JavaScript,每当触发点击事件时,都会去检查 body 标签的类列表是否具有dark_mode。如果有该类,则表示已启用暗色主题。因此,我们将从body 的类列表中删除dark_mode类,并将图像标签源更改为太阳图标。 如果类列表中没有任何名为dark_mode的类,则表示主题是浅色主题,并且由于发生了点击事件,我们使用 * classList.add切换到暗色主题,然后将img标签源替换为太阳图标。

让我们使用函数稍微清理一下代码。

theme_switcher.addEventListener("click",()=>{
    if(document.body.classList.contains("dark_mode")){
        lightMode()
    }else{
        darkMode()
    }
})

function darkMode(){
    document.body.classList.add("dark_mode")
    theme_switcher.setAttribute("src","./sun.png")
}

function lightMode(){
    document.body.classList.remove("dark_mode")
    theme_switcher.setAttribute("src","./moon.png")
}
Enter fullscreen mode Exit fullscreen mode

就是这样。现在,每当我们执行点击事件时,我们的切换图标就会进行主题切换

但这里有两个缺点。首先,如果刷新页面,主题会恢复为浅色;其次,如果你的网站上有多个页面,那么它的 body 标签将不具有暗色模式的类别。

通过解决第一个问题,我们也可以解决第二个问题。我们使用本地存储来实现这一点。

正如我之前所说,存储处理的是键值对。设键为theme_state,值设为disabled_state,这意味着网站处于系统默认状态。

现在将键值对保存到我们使用的存储中,

localStorage.setItem("theme_state", "disabled_state")
Enter fullscreen mode Exit fullscreen mode

这里我们基本上是告诉浏览器,获取这个键值对并将它们保存在存储中。

键是theme_state,值是disabled_state

现在,如果我们无法访问本地存储,那么保存到本地存储就毫无意义了。因此,我们使用getItem(key)来访问/获取数据,它会返回值,我们需要将其存储在一个变量中才能知道这个值是什么。

let storageValue=localStorage.getItem("theme_state")
Enter fullscreen mode Exit fullscreen mode

这是最重要的部分。

从存储中获取数据后,我们需要在点击发生时更改该键的值。但是,如果我们的getItem命令检查并发现本地存储为空,那么对于第一次在浏览器上运行该命令的开发人员来说,情况总是如此。

然后我们需要将本地存储设置为默认。
所以,让我们对代码进行一些修改。

let theme_switcher=document.querySelector("#switcher")

let storageValue=localStorage.getItem("theme_state")
if(storageValue===null){
    localStorage.setItem("theme_state","disabled_state")
}else if(storageValue==="enabled_state"){
    darkMode()
}


theme_switcher.addEventListener("click",()=>{
    storageValue=localStorage.getItem("theme_state")
    if(storageValue==="disabled_state"){
        darkMode()
    }else{
        lightMode()
    }
})

function darkMode(){
    localStorage.setItem("theme_state","enabled_state")
    document.body.classList.add("dark_mode")
    theme_switcher.setAttribute("src","./sun.png")
}

function lightMode(){
    document.body.classList.remove("dark_mode")
    localStorage.setItem("theme_state","disabled_state")
    theme_switcher.setAttribute("src","./moon.png")
}
Enter fullscreen mode Exit fullscreen mode

哎呀!代码有点多。我知道。我们来分解一下。
在运行这段代码之前,存储部分看起来是这样的。

前

运行代码后,它在启动时会获取键theme_state的值,但由于存储空间实际上是空的,所以找不到任何值。因此,它会返回null。如果返回null,我们将主题设置为默认主题,在本例中为浅色模式。

这是现在存储的样子。

后

好的,现在我们已经将存储设置为默认,但是我们需要在点击事件发生时更改值,对吗?正确。

theme_switcher.addEventListener("click",()=>{
    storageValue=localStorage.getItem("theme_state")
    if(storageValue==="disabled_state"){
        darkMode()
    }else{
        lightMode()
    }
})
Enter fullscreen mode Exit fullscreen mode

这就是我们编写这段代码的原因:告诉系统,当点击发生时,获取键的值,然后将其与字符串“disabled_state”进行比较。如果获取的值等于“disabled_state”,则需要将主题切换为暗黑模式,我们通过调用dark_mode()函数来实现这一点,函数代码如下。

function darkMode(){
    localStorage.setItem("theme_state","enabled_state")
    document.body.classList.add("dark_mode")
    theme_switcher.setAttribute("src","./sun.png")
}
Enter fullscreen mode Exit fullscreen mode

很简单吧。这就是存储和图标现在的样子。

点击

现在,以类似的方式,再次触发点击事件时,我们需要将存储值更改为disabled_state ,我们通过调用light_mode()函数来执行此操作,函数代码如下。

function lightMode(){
    document.body.classList.remove("dark_mode")
    localStorage.setItem("theme_state","disabled_state")
    theme_switcher.setAttribute("src","./moon.png")
}
Enter fullscreen mode Exit fullscreen mode

就是这样。
瞧!现在你知道了如何创建带有暗黑模式的网站。

我的建议是使用 .SVG 格式的图片/图标,因为它们即使压缩后看起来也很好,而且体积小。这也能加快网站的加载速度。

请评论您对黑暗模式和本文的看法。

祝您编码愉快。🤎

鏂囩珷鏉ユ簮锛�https://dev.to/belidenikhil/how-to-add-dark-mode-to-a-website-4646
PREV
提交提交后如何修复拼写错误
NEXT
农场堆栈 [ FastAPI +React+ mongoDB]