css/less 實現(xiàn)動態(tài)更換主題色

固定主題色的切換

思路:訪問網(wǎng)頁 => js讀取緩存(判斷是否有主題色的值,沒有就默認(rèn)皮膚奈偏,有則使用指定皮膚) => 用戶點擊換膚 => js切換對應(yīng)的css樣式文件即可 => 再將主題色的值寫入緩存

下面給大家兩種方式供選擇

切換css地址

<link type="text/css" rel="stylesheet" media="all" href="../theme1.css" id="theme_css" />
document.getElementById('theme_css').href = '../XXX.css';
假如我們有default.css / blue.css / red.css 三個主題泡徙,這樣我們就需要在書寫css的時候維護(hù)三個主題樣式表萍虽,js點擊切換的時候通過改變css樣式表鏈接來實現(xiàn)換膚功能轴脐。

**弊**:
- 需要同時維護(hù)N個文件
- js改變href屬性會帶來一定的延遲
HTML的rel屬性下的alternate實現(xiàn)
<link href="reset.css" rel="stylesheet" type="text/css">
<link href="default.css" rel="stylesheet" type="text/css" title="default">
<link href="blue.css" rel="alternate stylesheet" disabled type="text/css" title="blue">
<link href="red.css" rel="alternate stylesheet" disabled type="text/css" title="red">

css樣式文件大致分為三類:

  • 沒有title屬性债热,rel屬性值僅僅是stylesheet的<link>無論如何都會加載并渲染砾嫉,如reset.css;
  • 有title屬性窒篱,rel屬性值僅僅是stylesheet的<link>作為默認(rèn)樣式CSS文件加載并渲染焕刮,如default.css;
  • 有title屬性墙杯,rel屬性值同時包含alternate stylesheet的<link>作為備選樣式CSS文件加載配并,默認(rèn)不渲染,如blue.css和red.css高镐;

alternate意味備用溉旋,相當(dāng)于是 css 預(yù)加載進(jìn)來備用,所以不會有上面那種切換延時

使用方法:
JavaScript代碼修改<link>元素DOM對象的disabled值為false嫉髓,可以讓默認(rèn)不渲染的CSS開始渲染观腊。

// 需要換膚的時候傳入對應(yīng)的title即可,eg: skirColorChange( 'blue' );
var eleLinks = document.querySelectorAll('link[title]');
var skirColorChange = function ( value ) {
  eleLinks.forEach(function (link) {
      link.disabled = true;
      if (link.getAttribute('title') == value) {
          link.disabled = false;
      }
  });
}

  • 提前下載算行,會浪費單寬
  • 仍舊需要維護(hù)多個文件

動態(tài)色值的主題切換

如果是要實現(xiàn)動態(tài)換膚梧油,自定義色值,那上面的幾種方式就不適合了州邢。

思路:訪問網(wǎng)頁 => js讀取緩存(判斷是否有主題色的值儡陨,沒有就默認(rèn)皮膚,有則使用指定皮膚) => 用戶點擊換膚 => js切換主題色 => 再將主題色的值寫入緩存

下面給大家兩種方式供選擇

less的 modifyVars方法

modifyVars方法是是基于 less 在瀏覽器中的編譯來實現(xiàn)量淌。所以在引入less文件的時候需要通過link方式引入骗村,然后基于less.js中的方法來進(jìn)行修改變量

script引入less.min.js
<script type="text/javascript" src="/static/less.min.js" />
link方式引入主題色文件
<link rel="stylesheet/less" type="text/css" href="/static/public.less" />
更改主題色事件

// color 傳入顏色值
handleColorChange (color) {
    less.modifyVars({
         '@primaryColor':color
    })
    .then(() => {
         console.log('修改成功');
    });
};

如果工程型的項目,在webpack配置里開啟:

{
      test: /\.less$/,
      loader: 'less-loader',
      options: {
          javascriptEnabled: true
      }
},

如果是vueCli3.0/vueCli4.0,給大家一份完整的配置過程

  1. 首先在vue.config.js配置呀枢;
  css: {
    loaderOptions: {
      less: {
        modifyVars: {
          // 按需配置叙身,可配置多個
          'primary-color': 'red',
        },
        javascriptEnabled: true,
      }
    }
  },
  1. 在public/static/下創(chuàng)建color.less, 這個文件書寫所有涉及到需要改變的class及樣式;
@primaryColor: red;
.page {
  backgroud: @primaryColor;
  color: @primaryColor;
}
  1. 在public/static/下創(chuàng)建less.min.js硫狞;
  2. src/XXXX位置 創(chuàng)建setting.js信轿;
let lessNodesAppended;

const updateTheme = primaryColor => {
  if (!primaryColor) {
    return;
  }
  console.info(`正在編譯主題!`)
  function buildIt() {
    // 正確的判定less是否已經(jīng)加載less.modifyVars可用
    if (!window.less || !window.less.modifyVars) {
      return;
    }
    // less.modifyVars可用
    window.less.modifyVars({
        '@primary-color': primaryColor,
      })
      .then(() => {
        console.log(`成功`);
      })
      .catch(() => {
        console.error(`失敗`);
      });
  }
  if (!lessNodesAppended) {
    // insert less.js and color.less
    const lessStyleNode = document.createElement('link');
    const lessConfigNode = document.createElement('script');
    const lessScriptNode = document.createElement('script');
    lessStyleNode.setAttribute('rel', 'stylesheet/less');
    // 下方這個color.less位置大家也可以按需修改
    lessStyleNode.setAttribute('href', __webpack_public_path__ + 'static/color.less')
    lessConfigNode.innerHTML = `
      window.less = {
        async: true,
        env: 'production',
        javascriptEnabled: true
      };
    `;
    // less的src地址也可以是cdn地址
    lessScriptNode.src = '/static/less.min.js';
    lessScriptNode.async = true;
    lessScriptNode.onload = () => {
      buildIt();
      lessScriptNode.onload = null;
    };
    document.body.appendChild(lessStyleNode);
    document.body.appendChild(lessConfigNode);
    document.body.appendChild(lessScriptNode);
    lessNodesAppended = true;
  } else {
    buildIt();
  }
};
export { updateTheme }
  1. ok晃痴,到此為止東西都準(zhǔn)備好了,那么接下來财忽,我們需要初始化了倘核,大家可以在main.js中調(diào)用updateTheme('默認(rèn)值/你需要的主題色值')
  2. 如果是頁面要切換仍舊是調(diào)用updateTheme('你需要的主題色值')即彪;
css 變量方法

如果項目里用的不是less, 那么還是用css的方法紧唱,通用且容易操作,使用css變量來進(jìn)行主題色的修改隶校,替換主題色變量漏益,然后用setProperty來進(jìn)行動態(tài)修改
用法就是給變量加--前綴,涉及到主題色的都改成var(--themeColor)這種方式
使用方式:

body{
   --primaryColor:red;
}
.page{
    backgroud: var(--primaryColor);
    color: var(--primaryColor);
}

要修改主題色時:
document.body.style.setProperty('--primaryColor', 'blue');

總結(jié)

至此深胳,總共給了大家4種換膚方案绰疤,如果有更好的方案,歡迎大家補充~~~

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末舞终,一起剝皮案震驚了整個濱河市轻庆,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌敛劝,老刑警劉巖余爆,帶你破解...
    沈念sama閱讀 206,126評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異夸盟,居然都是意外死亡蛾方,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,254評論 2 382
  • 文/潘曉璐 我一進(jìn)店門上陕,熙熙樓的掌柜王于貴愁眉苦臉地迎上來桩砰,“玉大人,你說我怎么就攤上這事唆垃。” “怎么了痘儡?”我有些...
    開封第一講書人閱讀 152,445評論 0 341
  • 文/不壞的土叔 我叫張陵辕万,是天一觀的道長。 經(jīng)常有香客問我沉删,道長渐尿,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 55,185評論 1 278
  • 正文 為了忘掉前任矾瑰,我火速辦了婚禮砖茸,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘殴穴。我一直安慰自己凉夯,他們只是感情好货葬,可當(dāng)我...
    茶點故事閱讀 64,178評論 5 371
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著劲够,像睡著了一般震桶。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上征绎,一...
    開封第一講書人閱讀 48,970評論 1 284
  • 那天蹲姐,我揣著相機與錄音,去河邊找鬼人柿。 笑死柴墩,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的凫岖。 我是一名探鬼主播江咳,決...
    沈念sama閱讀 38,276評論 3 399
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼隘截!你這毒婦竟也來了扎阶?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 36,927評論 0 259
  • 序言:老撾萬榮一對情侶失蹤婶芭,失蹤者是張志新(化名)和其女友劉穎东臀,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體犀农,經(jīng)...
    沈念sama閱讀 43,400評論 1 300
  • 正文 獨居荒郊野嶺守林人離奇死亡惰赋,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 35,883評論 2 323
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了呵哨。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片赁濒。...
    茶點故事閱讀 37,997評論 1 333
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖孟害,靈堂內(nèi)的尸體忽然破棺而出拒炎,到底是詐尸還是另有隱情,我是刑警寧澤挨务,帶...
    沈念sama閱讀 33,646評論 4 322
  • 正文 年R本政府宣布击你,位于F島的核電站,受9級特大地震影響谎柄,放射性物質(zhì)發(fā)生泄漏丁侄。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 39,213評論 3 307
  • 文/蒙蒙 一朝巫、第九天 我趴在偏房一處隱蔽的房頂上張望鸿摇。 院中可真熱鬧,春花似錦劈猿、人聲如沸拙吉。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,204評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽庐镐。三九已至恩商,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間必逆,已是汗流浹背怠堪。 一陣腳步聲響...
    開封第一講書人閱讀 31,423評論 1 260
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留名眉,地道東北人粟矿。 一個月前我還...
    沈念sama閱讀 45,423評論 2 352
  • 正文 我出身青樓,卻偏偏與公主長得像损拢,于是被迫代替她去往敵國和親陌粹。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 42,722評論 2 345