实施一个光明与黑暗的主题,以持久的React

本文详细介绍了如何使用React和CSS创建一个简单的网站主题切换功能,包括颜色选择、按钮设计、主题设置以及使用Web Storage实现主题保存和默认值。通过实例演示,教你如何轻松地在网站上添加酷炫的暗/亮主题切换功能。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

介绍(Introduction)

So, you’ve come to that point in the creation of your website where you want to do something that looks “cool”, and what’s cooler (or more on brand with 2020) than having a button that allows users to flip the theme of your site from light to dark (and back again).

因此,您到了网站创建的关键时刻,想要做一个看起来很“酷”的东西,并且比拥有一个允许用户翻转主题的按钮更酷(或者在2020年品牌上更酷)的网站您的网站从浅到黑(然后再返回)。

You’ve undoubtedly noticed the increasing number of websites out there that offer this functionality, but how easy is it to implement? I’ll tell you: relatively easy. As long as you know a little React and some CSS, this is going to be a (socially distanced) walk in the park.

毫无疑问,您已经注意到提供这种功能的网站越来越多,但是实施起来有多容易呢? 我告诉你:比较容易。 只要您了解一点React和一些CSS,这将是在公园中(相距一定距离)的步行路程。

All of the code for this tutorial is available here.An example of this project can be viewed here.

本教程的所有代码均在此处提供。可以在此处查看该项目的示例。

目标 (The goal)

To have a simple switch or set of buttons that users can press to change the website from a light theme to a dark theme (or theme 1 to theme 2), and back again.The user selection must also be remembered for the next time they visit the site.

要使用简单的开关或按钮组,用户可以按该按钮或按钮将网站从浅色主题更改为深色主题(或将主题1更改为主题2),然后再次返回。下次用户还必须记住用户的选择访问该网站。

Here is an example of the proposed solution:

这是建议的解决方案的示例:

Image for post

解决方案 (The solution)

Prerequisites:

先决条件:

You can either set up your React solution yourself, use an existing solution, or clone the following git repository:https://github.com/mojiwa/react-light-dark-theme.git

您可以自己设置React解决方案,使用现有解决方案或克隆以下git仓库: https : //github.com/mojiwa/react-light-dark-theme.git

For this example I’m using standard React with plain CSS. Node version is 14.10.1 which you can download here.

对于此示例,我将标准React与普通CSS结合使用。 节点版本为14.10.1,可在此处下载

If you are cloning the above repository, you’ll need to run npm install to get all the packages installed.

如果要克隆上述存储库,则需要运行npm installnpm install所有软件包。

Colour selection:

颜色选择:

Before we begin it’s important to think carefully about the colours you use for both light and dark. I’m not going to go into a whole lesson on the science of colour picking, but what I tend to do is pick two colours that work well when you invert them (e.g. a light colour for the background and a dark colour for the text that are swapped around when the theme is switched); and a highlight colour for links, underlines, buttons etc. that works well with either background/font colour.Finding these colours might take you a little while but it’s worth taking the time out to do this.

在开始之前,请仔细考虑您用于浅色和深色的颜色,这一点很重要。 我不会讲授颜色选择科学的完整课程,但我倾向于做的是选择两种在反转颜色时效果很好的颜色(例如,背景为浅色,文本为深色)切换主题时会互换); 以及用于链接,下划线,按钮等的突出显示颜色,可以与背景/字体颜色配合使用。找到这些颜色可能会花费您一些时间,但值得花些时间这样做。

For this article I’ll use the same colours I’ve chosen for my personal site as they work quite nicely together:

在本文中,我将使用为个人站点选择的相同颜色,因为它们可以很好地协同工作:

Light: https://www.colorhexa.com/e2e8f0Dark: https://www.colorhexa.com/1a202cHighlight: https://www.colorhexa.com/319795

浅色: https : //www.colorhexa.com/e2e8f0深色: https : //www.colorhexa.com/1a202c高亮显示: https : //www.colorhexa.com/319795

Image for post
Example theme colours
示例主题颜色

Getting started:

入门:

I’m going to be working in App.js and I’ll start by defining all my colours as constants so that I can refer to them easily in the code:

我将使用App.js,首先将所有颜色定义为常量,以便可以在代码中轻松引用它们:

const THEME_LIGHT_HEX = '#E2E8F0'
const THEME_DARK_HEX = '#1A202C';
const THEME_HIGHLIGHT_HEX = '#319795';

I’m going to also create an Enum to store the two themes so that I can execute a simple if/else statement on them when setting the theme later on. With that in mind, the skeleton outline for App.js now looks like this:

我还将创建一个枚举来存储两个主题,以便稍后在设置主题时可以对它们执行简单的if / else语句。 考虑到这一点,App.js的框架轮廓现在看起来像这样:

import React from 'react';const THEME_LIGHT_HEX = '#E2E8F0'
const THEME_DARK_HEX = '#1A202C';
const THEME_HIGHLIGHT_HEX = '#319795';
const THEMES = {
Light: THEME_LIGHT_HEX,
Dark: THEME_DARK_HEX
};function App() {
return (
<div>
This is an example of how we can set themes using React.
</div>
);
}export default App;

That’s enough to get us started. Ensure that you tell your index.js file to render <App /> into your html entry point (whether that’s ‘root’ or something else).

这足以使我们开始。 确保您告诉index.js文件将<App />呈现到html入口点(无论是“ root”还是其他)。

Creating the switch:

创建开关:

There are a lot of ways to toggle themes on a site. You could use a button, a checkbox or a toggle switch. It doesn’t matter what you use as any of them will work and the JavaScript code is going to be the same. It’s all down to personal preference at this point.

有很多方法可以切换网站上的主题。 您可以使用按钮,复选框或拨动开关。 不管您使用什么,都可以使用,并且JavaScript代码将相同。 这一切都取决于个人喜好。

I’m going to create two buttons, one to switch to light and one to switch to dark. We’re going to get into some CSS now to style the buttons (which will actually be styled divs as opposed to HTML buttons).

我将创建两个按钮,一个按钮切换为亮灯,另一个按钮切换为暗灯。 现在,我们将使用一些CSS来设置按钮的样式(实际上将样式设置为div,而不是HTML按钮)。

I have an index.css file that is imported into App.js. That’s where I’ll be creating my buttons. Again, there are a lot of ways to do this but I’m opting for the simplest way that doesn’t involve additional tooling/frameworks. Use whatever method you feel comfortable with for creating styled elements:

我有一个导入到App.js中的index.css文件。 那就是我要创建按钮的地方。 同样,有很多方法可以做到这一点,但是我选择了不涉及其他工具/框架的最简单方法。 使用适合的任何方法来创建样式化元素:

.button-holder {
display: flex;
}.theme-button-light {
height: 25px;
width: 60px;
border-radius: 10%;
padding: 2px;
display: flex;
align-items: center;
justify-content: center;
cursor: pointer;
background-color: #cbd5e0;
color: #1a202c;
}.theme-button-dark {
height: 25px;
width: 60px;
border-radius: 10%;
padding: 2px;
display: flex;
align-items: center;
justify-content: center;
cursor: pointer;
background-color: #2d3748;
color: #e2e8f0;
}.theme-button-light:hover {
background-color: #e2e8f0;
}.theme-button-dark:hover {
background-color: #1a202c;
}

You can then throw these into your page (don’t forget to import the css into App.js - see the full code output at the bottom of this article if you’re not sure how to do this):

然后,您可以将它们放入页面中(不要忘记将CSS导入App.js中-如果不确定如何执行此操作,请参阅本文底部的完整代码输出):

function App() {
return (
<div>
This is an example of how we can set themes using React.
<div className='button-holder>
<div className='theme-button-dark'>Dark</div>
<div className='theme-button-light'>Light</div>
</div>
</div>
);
}

You’ll end up with something that looks like this (note that there is a hover effect on the buttons for some simple user feedback):

您最终将得到如下所示的内容(请注意,按钮上有一个悬停效果,用于一些简单的用户反馈):

Image for post
Image for post

Wiring the buttons:

接线按钮:

The next thing we need to do is wire up the buttons to execute a function when you click them. Edit the two button divs so that they look like this:

我们需要做的下一件事是将按钮连接起来,以在单击它们时执行功能。 编辑两个按钮div,使它们如下所示:

<div className='theme-button-dark' onClick={() => applyTheme(THEMES.Dark)}>Dark</div>
<div className='theme-button-light' onClick={() => applyTheme(THEMES.Light)}>Light</div>

You’ll notice that we call the function “applyTheme”, but no such function yet exists, so let’s make that:

您会注意到我们将函数称为“ applyTheme”,但是尚不存在这样的函数,因此让我们进行以下操作:

function applyTheme(theme) {
}

Setting the theme:

设置主题:

To actually be able to see anything happen we need to set the background and text colours to what we’ve chosen. For the sake of simplicity, I’m going to achieve this by setting the body style of the page through JavaScript code:

为了真正能够看到发生的任何事情,我们需要将背景和文本颜色设置为我们选择的颜色。 为了简单起见,我将通过JavaScript代码设置页面的主体样式来实现此目的:

function applyTheme(theme) {
document.body.style.backgroundColor = theme; document.body.style.color = theme === THEMES.Dark ? THEMES.Light : THEMES.Dark;
}

All we’re doing above is setting the background colour to the theme passed in. We then set the text colour to the opposite by using an if statement to check whether we passed in the dark theme or the light theme (if you pass in the dark theme, set the text colour to be the light theme and vice versa).

上面我们要做的就是将背景颜色设置为传入的主题。然后,通过使用if语句来检查是否传入了深色主题或浅色主题(如果您传入了主题,则将文本颜色设为相反的颜色)。深色主题,将文本颜色设置为浅色主题,反之亦然)。

Now when you run it you’ll have something that looks like the proposed solution above:

现在,当您运行它时,您将看到类似于上面建议的解决方案的内容:

Image for post
Working implementation of theme switching
主题切换的工作实现

Persistence and defaults:

持久性和默认值:

The last thing left to do is to save the theme so that when the site is loaded again it remembers what was previously selected. We also need to make sure a theme is set the first time the site it loaded (so it’s not just the default white background). We achieve these things using web storage and either “ComponentDidMount” or “UseEffect” (the latter if you’re using React Hooks). This example project uses Hooks so if you’re not familiar with that you can read about it here.

剩下要做的最后一件事情就是保存主题,以便当再次加载该站点时,它可以记住先前选择的内容。 我们还需要确保在首次加载主题时设置了主题(因此,不仅仅是默认的白色背景)。 我们使用Web存储以及“ ComponentDidMount”或“ UseEffect”(如果您使用的是React Hooks,则为后者)来实现这些目的。 这个示例项目使用了Hooks,因此如果您不熟悉它可以在这里阅读

Web storage is a cool way to store information for web apps. You can read more about it here. We can use web storage to persist our theme locally so that even if we close the browser and reopen it, our selection will be saved. We also don’t need to worry about security concerns that we do with cookies as no data is ever transferred to the server - it all remains locally stored. The other advantage over cookies is that web storage is far more intuitive to use and it can store a lot more (up to 5MB for session storage, more for local).

Web存储是存储Web应用程序信息的一种很酷的方法。 您可以在此处了解更多信息。 我们可以使用网络存储在本地保留主题,这样即使关闭浏览器并重新打开它,也将保存选择。 我们也不必担心我们对cookie所做的安全性问题,因为没有数据传输到服务器-所有数据都保留在本地。 与cookie相比,另一个优点是Web存储使用起来更加直观,并且可以存储更多空间(会话存储最大5MB,本地存储更多)。

I’ve created two functions for web storage. One to commit the data, the other to retrieve it. They look like this:

我已经创建了两个用于Web存储的功能。 一个提交数据,另一个获取数据。 他们看起来像这样:

const THEME_KEY = 'THEME';// Save the chosen theme to web storage
function
SaveSettings(value) {
window.localStorage.setItem(THEME_KEY, value);
}// Get the saved theme from web storage
function
GetSettings() {
// Return the saved theme if a theme has been saved.
// If no theme has been saved, default to the light theme.
return window.localStorage.getItem(THEME_KEY) ?? THEMES.Light;
}

You can slot this code in just above your App function. To save the theme when we change it we simply need to call “SaveSettings()” with the theme when it’s changed. Update the “applyTheme()” method like so:

您可以将此代码放在App函数上方。 要在更改主题时保存主题,我们只需要在主题更改后调用“ SaveSettings()”即可。 像这样更新“ applyTheme()”方法:

function applyTheme(theme) {
document.body.style.backgroundColor = theme; document.body.style.color = theme === THEMES.Dark ? THEMES.Light : THEMES.Dark; SaveSettings(theme);
}

To apply the saved settings (or default to the light theme on first load) when you open the page you can either do the below (if you’re using React Hooks), or just call the same function in ComponentDidMount():

要在打开页面时应用保存的设置(或在首次加载时默认应用到浅色主题),您可以执行以下操作(如果使用的是React Hooks),也可以在ComponentDidMount()中调用相同的函数:

// When we load the site, we attempt to get the saved theme from web storage.useEffect(() => {
applyTheme(GetSettings());
});

And that’s it. You now have a theme switch that flips between a light and dark theme and saves that to local web storage.

就是这样。 现在,您有了一个主题开关,可以在浅色和深色主题之间切换并将其保存到本地Web存储中。

The final code should look like this:

最终代码应如下所示:

App.js

App.js

import React from 'react';
import './index.css';const THEME_LIGHT_HEX = '#E2E8F0'
const THEME_DARK_HEX = '#1A202C';
const THEME_HIGHLIGHT_HEX = '#319795';
const THEMES = {
Light: THEME_LIGHT_HEX,
Dark: THEME_DARK_HEX
};
const THEME_KEY = 'THEME';// Save the chosen theme to web storage
function
SaveSettings(value) {
window.localStorage.setItem(THEME_KEY, value);
}// Get the saved theme from web storage
function
GetSettings() {
// Return the saved theme if a theme has been saved.
// If no theme has been saved, default to the light theme.
return window.localStorage.getItem(THEME_KEY) ?? THEMES.Light;
}function App() {
// When we load the site, we attempt to get the saved theme from web storage.
useEffect(() => {
applyTheme(GetSettings());
});function applyTheme(theme) {
document.body.style.backgroundColor = theme;
document.body.style.color = theme === THEMES.Dark ? THEMES.Light : THEMES.Dark;
SaveSettings(theme);
}return (
<div>
This is an example of how we can set themes using React.
<div className='button-holder>
<div className='theme-button-dark' onClick={() => applyTheme(THEMES.Dark)}>Dark</div>
<div className='theme-button-light' onClick={() => applyTheme(THEMES.Light)}>Light</div>
</div>
</div>
);
}export default App;

index.css

index.css

.button-holder {
display: flex;
}.theme-button-light {
height: 25px;
width: 60px;
border-radius: 10%;
padding: 2px;
display: flex;
align-items: center;
justify-content: center;
cursor: pointer;
background-color: #cbd5e0;
color: #1a202c;
}.theme-button-dark {
height: 25px;
width: 60px;
border-radius: 10%;
padding: 2px;
display: flex;
align-items: center;
justify-content: center;
cursor: pointer;
background-color: #2d3748;
color: #e2e8f0;
}.theme-button-light:hover {
background-color: #e2e8f0;
}.theme-button-dark:hover {
background-color: #1a202c;
}

普通英语JavaScript (JavaScript In Plain English)

Enjoyed this article? If so, get more similar content by subscribing to Decoded, our YouTube channel!

喜欢这篇文章吗? 如果是这样,请订阅我们的YouTube频道解码,以获得更多类似的内容

翻译自: https://medium.com/javascript-in-plain-english/implementing-a-light-and-dark-theme-in-react-with-persistence-329aa4bc4da5

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值