需求背景:
单一的视觉不再满足用户(消费者)体验需求,为提高用户体验,因此提供主题切换(换肤)功能,允许用户将应用切换不同主题风格的皮肤,从而提高用户视觉效果及体验。
实现方式:
1. 根据根节点不同class进行切换
实现原理:
- 准备多套主题色,如dark,default两套主题
- 根据选择不同的主题色来切换根节点下的不同class
```css
<!DOCTYPE html>
当前主题色为:gray
<a name="yekLN"></a>
### 优点:
- 简单易懂,不需要额外技术支持
- 兼容性较好
<a name="DrVVk"></a>
### 劣势:
- 需维护多套主题,人工耗时较长
<a name="IVk6R"></a>
## 2. CSS变量
<a name="Q2uj2"></a>
### 实现原理:
- 创建具有全局作用域的变量,请在 :root(或其他元素)选择器中声明它
- 使用 var() 函数在样式表中插入变量的值
- 根据选择不同的主题去动态切换主题色
```css
<!DOCTYPE html>
<html lang="en">
<head>
<style>
:root {
--primary-color: gray;
}
div {
width: 100px;
height: 100px;
background: var(--primary-color);
}
</style>
</head>
<body>
<div></div>
<p>当前主题色为:<span class="currentTheme">gray</span></p>
<button onClick="toggleTheme()">主题色切换</button>
<script>
const themes = ["gray", "black"];
function toggleTheme() {
var currentTheme = getComputedStyle(document.documentElement)
.getPropertyValue("--primary-color")
.trim();
var toggleTheme = themes.filter((_) => _ !== currentTheme)[0];
document.documentElement.style.setProperty(
"--primary-color",
toggleTheme
);
document.querySelector(".currentTheme").innerText = toggleTheme;
}
</script>
</body>
</html>
优点:
- 使代码更易于阅读及理解
-
劣势:
兼容性较差
-
3. 浏览器中less动态编译
实现原理:
找到项目所有的 less,并且将其中带有 less 的变量的选择器抽出,组合成一个新的 less,也就是 color.less
- 在浏览器中通过 less.js 来编译他,然后覆盖掉原本的属性
```css
<!DOCTYPE html>
当前主题色为:gray
<a name="GJpB5"></a>
### 优点:
- 支持任何颜色的主题切换
<a name="qF01H"></a>
### 劣势:
- 需额外加载less.js文件
- less编译工作在浏览器端进行,会比较消耗耗时且可能在换肤时出现白屏现象
<a name="MayzW"></a>
### 备注:
如直接打开对应Html文件,会报跨域问题,这是由于谷歌浏览器中的安全问题导致的<br />解决办法:本地启动web服务器
<a name="CkQKR"></a>
### less浏览器端编译实现:
- 初始化时调用registerStylesheetsImmediately方法,把当前引入的less文件放入less.sheets中
```css
less.registerStylesheetsImmediately()
var typePattern = /^text\/(x-)?less$/;
less.registerStylesheetsImmediately = function () {
var links = document.getElementsByTagName('link');
less.sheets = [];
for (var i = 0; i < links.length; i++) {
if (links[i].rel === 'stylesheet/less' || (links[i].rel.match(/stylesheet/) &&
(links[i].type.match(typePattern)))) {
less.sheets.push(links[i]);
}
}
};
- 再调用其less.refresh方法 ```css less.pageLoadFinished = less.refresh(less.env === ‘development’);
less.refresh = function (reload, modifyVars, clearFileCache) { return new Promise(function (resolve, reject) { remainingSheets = less.sheets.length; if (remainingSheets === 0) { less.logger.info(‘Less has finished and no sheets were loaded.’); } else { loadStyleSheets(function (e, css, _, sheet, webInfo) { if (e) { errors.add(e, e.href || sheet.href); reject(e); return; } if (webInfo.local) { less.logger.info(“Loading “ + sheet.href + “ from cache.”); } else { less.logger.info(“Rendered “ + sheet.href + “ successfully.”); } browser.createCSS(window.document, css, sheet); less.logger.info(“CSS for “ + sheet.href + “ generated in “ + (new Date() - endTime) + “ms”); if (remainingSheets === 0) { resolve({ sheets: less.sheets.length }); } }, reload, modifyVars); } loadStyles(modifyVars); }); }; ```
