通常,前端一键换肤功能需要通过使用 CSS 样式表来定义不同的主题样式,然后通过 JavaScript 来控制切换不同的样式表,以达到换肤的效果。用户在点击换肤按钮或者选择不同的主题选项后,页面会立即应用新的样式,从而改变界面的外观。这种功能在很多网站、应用中都有广泛的应用,特别是一些内容丰富、用户群体广泛的平台,以满足不同用户对于外观风格的偏好。
今天我就教大家用两种方式实现前端一键换肤的功能,都是给予原生 css 和 js 的方法属性,不用安装任何的第三方库
第一种方法:window.document.documentElement.style.setProperty()
先介绍一下 window.document.documentElement.style.setProperty()这个方法 document.documentElement代表的是文档对象模型(DOM)中的根元素,即HTML文档中的元素。style.setProperty()是用于在JavaScript中设置元素样式的方法。 具体来说,document.documentElement.style.setProperty() 方法可以用于动态地设置根元素的 CSS 样式属性。它接受两个参数:
- 属性名: 第一个参数是要设置的 CSS 属性名称,例如 "color", "font-size", "background-color" 等等。
- 属性值: 第二个参数是要为属性设置的值,可以是字符串或者变量,表示对应样式属性的值。
例如,以下代码将修改根元素的背景颜色为红色:
javascript
document.documentElement.style.setProperty('background-color', 'red');
这种方法可以用于动态改变页面的整体样式,在实现一键换肤功能时非常有用。通过 JavaScript 动态地调用 setProperty() 方法,可以实现在用户操作后改变整个页面的外观,从而实现换肤的效果。
话不多说,show time 时间到!看我操作,我只演示一遍!
打开前端项目,在 src 项目下创建一个 theme 文件夹用来保存主题样式相关的 css 和 js 文件。我这里默认有两种主题,分别是黑夜和白昼。你可以根据自己的项目情况来设置有多少种主题。
在 theme 文件夹种创建 dark.ts,light.ts 和 theme.css 等三个文件。
首先在 theme.css 文件中的 root 根选择器里面定义默认的 css 变量
css
:root {
--bgColor: #000000;
}
然后在项目的根样式 index.css 文件中去导入,这样就可以全局使用 css 的自定义的变量了
css
@import "src/theme/theme.css";
html, body {
padding: 0;
margin: 0;
background: var(--bgColor);
}
在 dark.ts 和 light.ts 文件中写入对应主题下的样式,只不过是用 js 的方式去写
typescript
const dark: any = {
bgColor: '#000',
}
typescript
const light: any = {
bgColor: '#3ce035',
}
然后在两个文件中使用 document.documentElement.style.setProperty('css 变量', '属性值')
的方法来修改 root 选择器中定义的 css 变量的值
typescript
const dark: any = {
bgColor: '#000',
}
function setTheme(theme: any) {
const root = document.documentElement;
for (const key in theme) {
root.style.setProperty(`--${key}`, theme[key]);
}
}
export default () => setTheme(dark)
typescript
const light: any = {
bgColor: '#3ce035',
}
function setTheme(theme: any) {
const root = document.documentElement;
for (const key in theme) {
root.style.setProperty(`--${key}`, theme[key]);
}
}
export default () => setTheme(light)
然后把两个方法都导出,在切换主题的地方调用即可
我使用的演示项目是基于 react 的,vue 项目也是差不多的,都是相通的
在 App.tsx 组件中导入两个修改主题的方法
tsx
import './App.css'
import {Select} from "antd";
import {useState} from "react";
import dark from "./theme/dark.ts";
import light from "./theme/light.ts";
function App() {
const [value, setValue] = useState<string>('dark')
return (
<>
<div>
<Select value={value} onChange={value => {
console.log(value)
setValue(value)
if (value === 'dark') {
dark()
} else if (value === 'light') {
light()
}
}}>
<Select.Option value={'dark'}>黑色</Select.Option>
<Select.Option value={'light'}>白色</Select.Option>
</Select>
</div>
</>
)
}
export default App
黑色主题
白色主题
以上就大功告成了,不过要注意的是 css 的自定义变量名称要保持一致哦,这就是第一种方法。是不是很简单?别慌下面还有更加简单的。
第二种方法:html 自定义属性配合 css 的属性选择器
当谈到HTML自定义属性和CSS的属性选择器时,它们分别是HTML和CSS中非常有用的功能。让我详细介绍一下它们:
HTML自定义属性:
在HTML中,可以使用自定义属性来存储额外的信息或数据,这些属性并不会影响文档的结构或样式,但可以通过JavaScript或CSS来访问和操作。自定义属性通常以data-开头,例如data-color="red"。
示例:
html
htmlCopy Code<div data-color="red">This is a red box</div>
在JavaScript中,你可以使用getAttribute()方法来获取自定义属性的值:
javascript
javascriptCopy Codevar color = document.querySelector('div').getAttribute('data-color');
console.log(color); // 输出 "red"
CSS的属性选择器:
CSS属性选择器允许你根据元素的属性值来选择元素。常见的属性选择器包括:
[attribute]
: 选择具有指定属性的元素。[attribute=value]
: 选择属性值等于特定值的元素。[attribute~=value]
: 选择属性值包含特定词的元素。[attribute|=value]
: 选择属性值以特定值开头(包括该值和后面的连字符)的元素。[attribute^=value]
: 选择属性值以特定值开头的元素。[attribute$=value]
: 选择属性值以特定值结尾的元素。[attribute*=value]
: 选择属性值包含特定值的元素。
示例:
css
cssCopy Code/* 选择所有包含data-color属性的元素 */
[data-color] {
color: blue;
}
/* 选择data-color值为"red"的元素 */
[data-color="red"] {
color: red;
}
使用CSS属性选择器可以根据元素的自定义属性值来样式化元素,为页面的样式定制提供了更多灵活性和控制力。
第二种方法就是使用的以上的两个方法的结合起来,来实现一键爱换肤的功能的
话不多说,看我操作
还是在 theme 文件夹下面创建两个 css 文件。一个 dark.css,一个 light.css,然后在文件中分别写入对应主题下的样式
css
[data-theme="dark"] {
--bgColor: #052341;
}
[data-theme="light"] {
--bgColor: #3ce035;
}
然后把这两个样式文件分别引入到 index.css 根样式文件中
css
/*@import "src/theme/theme.css";*/
@import "src/theme/dark.css";
@import "src/theme/light.css";
html, body {
padding: 0;
margin: 0;
background: var(--bgColor);
}
然后在 App.tsx 也就是修改主题的地方去设置对应的 html 自定义属性即可达到换肤的效果了
tsx
import './App.css'
import {Select} from "antd";
import {useState} from "react";
function App() {
const [value, setValue] = useState<string>('dark')
document.documentElement.setAttribute('data-theme', value)
return (
<>
<div>
<Select value={value} onChange={value => {
console.log(value)
setValue(value)
if (value === 'dark') {
document.documentElement.setAttribute('data-theme', 'dark')
} else if (value === 'light') {
document.documentElement.setAttribute('data-theme', 'light')
}
}}>
<Select.Option value={'dark'}>黑色</Select.Option>
<Select.Option value={'light'}>白色</Select.Option>
</Select>
</div>
</>
)
}
export default App
我这里是设置的 dark 主题为默认主题。
以上就是比较简单的两种一键换肤的功能的实现了,我个人感觉第二种比第一种写起来要简单优雅一点。不过话说回来,咱管那么多?实现功能就行,代码和人有一个能跑就行啦,哈哈哈。
觉得我写的不错的 jym 欢迎评论讨论呀