文章目錄
網站主題切換
前言
關於網站主題的切換,其實也叫網站換膚。
記得以前博客流行的時代,換膚很受歡迎。也在那時候,就有想過這些事怎麼實現的,不過那時的我還是名學生,也沒有接觸過網站的製作知識。
如今,我成了一名前端開發者,也工作的幾年了,卻一直沒有接到過類似的需求,想來也奇怪。
但爲了曾經的一點念想,用現在的知識來實現一下。
思路
顏色,肯定是通過css
來顯示的,但css
有三種寫法:
-
style
屬性 -
style
標籤 -
外部
css
文件
如果要實現網站的換膚效果,首先得統一與顏色相關的
css
的寫法,在這裏建議要麼寫在style屬性中,要麼寫在外部css
文件中
全部寫在style
屬性中
思路:對於這中寫法,我們可以在全局配置主題色變量,然後通過js
代碼將主題色寫入對應標籤的style
屬性中。當主題色發生變化的時候,通知修改所有相關的標籤的style
屬性。
適用類型:適用於用vue
這種雙向數據綁定的項目,變量發生改變是自動更新視圖。
優點:完全通過代碼就可實現
缺點:對代碼的要求高,只適用小項目,而且增加了代碼的可維護性。
全部寫在外部css
文件中
有三種實現方式:
-
引用不同的
link
文件 -
通過
class
命名空間的方式 -
webpack
插件:webpack-theme-color-replacer
引用不同的link
文件
思路:根據不同的主題,先寫好對應的css
文件。然後,在通過代碼根據用戶選擇的主題,去加載對應的主題css
文件。
適用類型:項目只需要幾種固定的主題
優點:主題樣式可以變化的空間很大
缺點:只能切換設計好的主題
通過class
命名空間的方式
思路:根據不同的主題,設置對應的class命名空間。然後,在通過代碼根據用戶選擇的主題,去切換對應的class。其實第一種方式有異曲同工之處。
適用類型:項目只需要幾種固定的主題
優點:主題樣式可以變化的空間很大
缺點:只能切換設計好的主題
webpack
插件:webpack-theme-color-replacer
最近看到element-ui
、ant-design
、iview
的網站換膚功能都用到了webpack-theme-color-replacer
,發現這是目前最好的一種網站主題色切換方式。
思路:
webpack-theme-color-replacer
的思路是先通過webpack
打包時,將主題色的顏色值與css
文件進行匹配,提取匹配到的css
樣式單獨生成一個theme-color.css
。
當用戶修改主題色時,先讀取theme-color.css
中的內容並將主題色進行替換,最後在再將樣式寫入到html
文件中的style
標籤中,從而實現了主題切換。
適用類型:中後臺系統,主題色的顏色按照淡化的方式變化
優點:可以隨意切換主題色
缺點:主題色的顏色按照淡化的方式變化
實現
在這裏只實現利用webpack
插件:webpack-theme-color-replacer
這一種方法,其他方法網上有很多例子。
webpack-theme-color-replacer
第一步,安裝插件
npm i -D webpack-theme-color-replacer
第二步,配置webpack
const WebpackThemeColorReplacer = require('webpack-theme-color-replacer')
new WebpackThemeColorReplacer({
fileName: 'css/theme-colors-[contenthash:8].css',
// 根據匹配的css樣式生成單獨的css文件
matchColors: [
...forElementUI.getElementUISeries('#FF0000'),
// 根據主題色生成一系列顏色(10個),適用於ElementUI、Ani Design、Iview等組件
'#FF0000'
// 自定義的主題色
],
// 需要匹配的網站主題色
resolveCss(resultCss) {
return resultCss.replace(/#4b0/g, '#ed4040')
},
// 將匹配的顏色值替換
externalCssFiles: [],
// 外部css文件,比如引用了第三方的css文件
changeSelector(cssSelector) {
return cssSelector
},
isJsUgly: process.env.NODE_ENV !== 'development'
// 壓縮生成的css文件
})
第三步,項目加入切換代碼
import replacer from 'webpack-theme-color-replacer/client'
// 引入插件方法
function changeColor(newColor) {
var options = {
newColors: [...forElementUI.getElementUISeries(newColor), newColor],
// 傳入的新的主題色
changeUrl(cssUrl) {
return `/${cssUrl}`
}
// 如果需要加載自定義的css文件
// 這種方式就像加載外部link一樣
}
replacer.changer.changeColor(options, Promise).then(() => {
console.log('Theme colors changed!')
})
// 執行切換主題方法,返回promise
}
changeColor('#FF3333')
// 用戶切換主題色時觸發切換方法
所有的主題色相關的
css
樣式都需要寫在css
外部文件中,如果寫在了style
屬性上,切換時不會生效