整合營銷服務商

          電腦端+手機端+微信端=數據同步管理

          免費咨詢熱線:

          前端最全的5種換膚方案總結

          前端最全的5種換膚方案總結:打造個性化的用戶體驗之旅

          ### **引言:為什么換膚功能至關重要**

          隨著Web應用逐漸重視用戶體驗設計,前端頁面的個性化定制愈發重要。換膚功能作為一種增強用戶參與感和滿意度的有效途徑,讓訪問者可以根據個人喜好調整界面風格。本文將深入探討五種前沿且廣泛應用的前端換膚方案,每一種方案都有詳細的原理介紹及實戰代碼演示,助您輕松應對各種場景下的前端換膚需求。

          ### **方案一:CSS自定義屬性(CSS Variables)**

          #### **1.1 CSS Variables基礎**

          CSS Variables允許開發者定義全局或局部的樣式變量,從而實現動態更換皮膚顏色。

          ```html

          <!DOCTYPE html>

          <html lang="en">

          <head>

          <style>

          :root {

          --main-color: #1abc9c;

          --secondary-color: #ecf0f1;

          }

          body {

          background-color: var(--main-color);

          color: var(--secondary-color);

          }

          </style>

          </head>

          <body>

          ...

          </body>

          </html>

          ```

          #### **1.2 利用JavaScript動態更新CSS Variables**

          通過JavaScript更改根元素上的CSS變量值,進而實現一鍵換膚:

          ```javascript

          document.documentElement.style.setProperty('--main-color', '#3498db');

          document.documentElement.style.setProperty('--secondary-color', '#bdc3c7');

          ```

          ### **方案二:CSS主題文件切換**

          #### **2.1 主題樣式表切換**

          創建多個CSS主題文件,通過JavaScript切換 `<link>` 標簽指向的不同CSS文件實現換膚:

          ```html

          <button onclick="changeTheme('dark')">切換到深色主題</button>

          <script>

          function changeTheme(themeName) {

          let linkElement = document.querySelector('#theme-css');

          linkElement.href = `themes/${themeName}.css`;

          }

          </script>

          <!-- 默認引入淺色主題 -->

          <link id="theme-css" rel="stylesheet" href="themes/light.css">

          ```

          ### **方案三:Less / Sass 預處理器**

          #### **3.1 Less / Sass 變量和Mixins**

          使用預處理器定義主題色彩變量,并在樣式中引用:

          ```less

          // Less 文件

          @main-color: #ff5e14;

          body {

          background-color: @main-color;

          }

          // 更改主題時只需更改變量值

          @main-color: #2ecc71;

          ```

          #### **3.2 編譯多主題CSS**

          通過構建工具(如Gulp、Webpack)在構建階段生成不同主題的CSS文件。

          ### **方案四:JavaScript 動態樣式注入**

          #### **4.1 動態DOM樣式修改**

          遍歷DOM樹,針對具有特定數據屬性(例如 `data-theme`)的元素直接修改其樣式:

          ```html

          <div data-theme="background">...</div>

          <script>

          const newColor = '#2980b9';

          document.querySelectorAll('[data-theme]').forEach((el) => {

          el.style.backgroundColor = newColor;

          });

          </script>

          ```

          #### **4.2 類名切換法**

          利用CSS類名切換,配合JavaScript添加/移除類名實現換膚:

          ```html

          <body class="theme-default">...</body>

          <style>

          .theme-light { background-color: #f9f9f9; }

          .theme-dark { background-color: #333; }

          </style>

          <script>

          function switchTheme() {

          const body = document.body;

          if (body.classList.contains('theme-light')) {

          body.classList.remove('theme-light');

          body.classList.add('theme-dark');

          } else {

          // 切換回默認或其他主題

          }

          }

          </script>

          ```

          ### **方案五:基于JSON配置的動態換膚**

          #### **5.1 JSON主題配置**

          存儲主題信息于JSON文件中:

          ```json

          {

          "theme": {

          "backgroundColor": "#F0F0F0",

          "textColor": "#333",

          "linkColor": "#007BFF"

          }

          }

          ```

          #### **5.2 從JSON加載并應用主題**

          通過Ajax請求獲取JSON配置,然后根據數據動態生成CSS規則:

          ```javascript

          fetch('themes/current_theme.json')

          .then(response => response.json())

          .then(data => {

          const style = document.createElement('style');

          const rules = Object.entries(data.theme).map(([prop, value]) => {

          return `${prop}: ${value};`;

          }).join('');


          style.textContent = `

          body { ${rules} }

          /* 其他元素樣式 */

          `;


          document.head.appendChild(style);

          });

          ```

          ### **結語:選擇適合的換膚方案**

          以上五種前端換膚方案各有優劣,具體選用哪一種取決于項目的具體需求、現有技術棧以及對性能優化的考量。無論采用何種方式,始終要關注用戶體驗,確保換膚過程流暢自然。持續學習和嘗試新技術,我們就能打造出更加貼合用戶喜好的前端產品,從而提高用戶黏性和滿意度。

          果圖:

          • CSS變量的基本使用
          <!DOCTYPE html>
          <html lang="en">
          <head>
              <meta charset="UTF-8"/>
              <meta http-equiv="X-UA-Compatible" content="IE=edge"/>
              <meta name="viewport" content="width=device-width, initial-scale=1.0"/>
              <title>Document</title>
              <style>
                  /*  :root是一個偽類,表示文檔根元素 */
          
                  /* 可以理解聲明了一些全局變量 */
                  :root {
                      --text-default-color: #fff;
                      --text-highlight-color: #03a9f4;
                      --bg-color: #1b2426;
                  }
          
                  .container {
                      height: 100px;
                      line-height: 2;
                      color: var(--text-default-color);
                      background: var(--bg-color);
                  }
          
                  .container span {
                      color: var(--text-highlight-color);
                  }
              </style>
          </head>
          
          <body>
              <div class="container">
                  Lorem ipsum dolor sit amet <span>consectetur</span> adipisicing elit. Commodi delectus
                  <span>inventore</span> repudiandae repellat assumenda quaerat a impedit <span>perferendis</span> facilis quos,
                  odio animi aut et illum accusamus ducimus minus, voluptatem dolorem!
              </div>
          </body>
          </html>
          • 實現換膚功能

          端換膚方案 - element+less無感換膚(無需頁面刷新)

          前言

          前不久在改造一個迭代了一年多的項目時,增加了一個換膚功能。通過自己的探索,總結出了一套比較合適的改造方案供大家參考,如有更好的方案歡迎評論區踴躍評論

          先上效果:

          聊聊現有方案

          在查閱現有方案時,總結了目前使用的幾種方案:

          1、定義多套樣式

          首先定義一套或多套樣式變量,包括淺色和深色兩種主題。在scss或less中使用變量,通過js改變root節點的class或屬性來達到樣式覆蓋。 這種方式實現的前端換膚方案,可能會導致樣式不易管理,查找樣式復雜,每一套皮膚需要寫一個css文件,造成多個css代碼冗余。

          $dark-fill-1: #222;  
          $dark-color-text: #fff;   
          $dark-color-text-1: rgba(255,255,255,0.3);   
          $dark-color-text-2: $color-brand1;
          
          [data-theme="dark"] {   
            body { background: $dark-fill-1; }   
            .item .name { color: $dark-color-text; }   
            .item .desc { color: $dark-color-text-1; }   
            .header .text { color: $dark-color-text-2; }   
          }
          

          2、使用less傳參

          通過less或scss的傳參屬性,同樣的只要改變根節點class或屬性即可以改變頁面樣式,與第一點的優點是不需要寫多份css文件,缺點是通過方法傳入,當樣式過多時,參數過多,需要改變某一個顏色成本高,容易造成問題。

          .theme(
              @mainPageBG: #f4f6ff,
              @fColor: #1b1e29,
              @vanBgColor: rgb(198, 183, 140),
              @vanColor: #fff
          ) {
              .home {
                  background: @mainPageBG;
                  color: @fColor;
              }
          }
          
          .themeWhite {
              .theme(#fff, #1b1e29, rgb(198, 183, 140), #fff);
          }
          .themeBlack {
              .theme(#090c14, #fff, rgb(198, 183, 140), #fff);
          }
          

          3、VueUse+css變量快速切換

          使用外部庫VueUse的useDark快速切換黑暗和明亮模式。

          <script setup lang="ts">
          import { useToggle } from '@vueuse/shared'
          import { isDark } from '../../.vitepress/theme/composables/dark'
          
          // const isDark = useDark()
          const toggleDark = useToggle(isDark)
          </script>
          
          <template>
            <button @click="toggleDark()">
              <i inline-block align-middle i="dark:carbon-moon carbon-sun" />
          
              <span class="ml-2">{{ isDark ? 'Dark' : 'Light' }}</span>
            </button>
          </template>
          

          最終解決方案

          接觸了解了上述幾個方案后,結合項目本身架構(less+element+echarts+map),最終采用了以下使用方案。

          less變量處理

          1、定義不同膚色的css變量

          .themeDark {
              --theme-color: #141414;
              --header-primary-color: #1a3750;
              --bg-content-default: #1a3750;
              --bg-theme-default: #13293b;
              --bg-left-color: #27415a;
          }
          
          .themeLight {
              --theme-color: #f4f4f4;
              --header-primary-color: #2670ff;
              --bg-content-default: #fff;
              --bg-theme-default: #f3f5f9;
              --bg-left-color: #eff3f4;
          }
          

          2、引入css變量,并通過定義less變量使用,解決了通過方法傳參,參數過多的問題。

          //換膚相關
          @import './dark.less';
          @import './light.less';
          
          @theme-color: var(--theme-color-te);
          @header-primary-color: var(--header-primary-color);
          @bg-content-default: var(--bg-content-default);
          @bg-left-color: var(--bg-left-color);
          @bg-theme-default: var(--bg-theme-default);
          @font-default-color: var(--font-default-color);
          

          element 主題切換

          1、可以在element官網定制和下載不同主題的style文件,將css文件更名為less,在最外層增加自定義的類。

          .themeDark{
              //下載的css文件
              ...
          }
          

          2、為了開發中不用每次去編譯這個較大的less文件,再通過less命令,將less轉為css

          lessc + 空格 + less文件名
          
          

          最終效果:

          @charset "UTF-8";
          .themeDark .fade-in-linear-enter-active,
          .themeDark .fade-in-linear-leave-active {
            -webkit-transition: opacity 0.2s linear;
            transition: opacity 0.2s linear;
          }
          ...
          

          3、main.js中引入

          echarts

          因為項目中使用了大量的echarts,在動態切換膚色時echarts需要重新加載才能改變,因此,需要通過監聽全局變量,當改變皮膚時重新渲染echarts。將當前主題存放到vuex中

          watch:{
                  '$store.state.myTheme'() {
                      this.getAllData();
                  }
          }
          

          map

          項目中使用到了騰訊地圖,所以也需要更改在不同主題下不同的地圖主題。在使用地圖時我們知道,在引入地圖時需要去引入地圖的入口文件,入口文件中包含著需要加載的地圖資源,所以我們只需要在騰訊地圖官網定義不同的主題顏色,將其style.json保留下來,修改入口文件中的配置。

          ...
          styleSrc: theme == 'themeDark' ? '/static/style.json' : 'https://xxxx/static/cdn/style{id}/style.json',
          style3DSrc:  theme == 'themeDark'  ? '/static/style.json' : 'https://xxxx/static/cdn/style{id}/style.json',
          ...
          

          js改變主題

          做好以上準備工作,在main.js中在改變html的上的屬性以及vuex來實現不用刷新更換不同主題。

          將需要設置的主題存放到Storage中,以保證刷新后主題顏色不變,為了兼容UI框架(比如dialog會將dom渲染到body外),所以將class置于最頂層html上,改變主題的時候改變html上的class,這樣下層所有的less變量將會使用該class下的顏色主題。修改vuex的值,用于觸發echarts的刷新。

          /**
          * 切換膚色
          */
          changeColor(type) {
              this.themeClass = type;
              window.sessionStorage.setItem('themeClass', this.themeClass);
              //動態修改html class,為了兼容UI框架,將class置于最頂層
              const themeArr = ['themeDark', 'themeLight'];
              let tempArr = document.querySelector('html').classList;
              tempArr.forEach((item) => {
                  if (themeArr.includes(item)) {
                      document.querySelector('html').classList.remove(item);
                  }
              });
              document.querySelector('html').classList.add(this.themeClass);
          
              //修改echarts的顏色
              if (type == 'themeLight') {
                  Vue.prototype.$themeChartColor = '#333';
              } else {
                  Vue.prototype.$themeChartColor = '#fff';
              }
              //修改store的值,可用于觸發相操作
              this.$store.commit('setMyTheme', type);
          },
          

          結語

          以上便是本次換膚分享,由于該項目剛開發時并沒有考慮到后續需要換膚的方案,在本次開發時也遇到很多細節問題,比如之前開發時主題色、各種狀態顏色標準使用不一致,改造時我盡量去將一些相近的顏色做到統一,保持系統整體一致性。本次迭代也用了較短的時間實現了這個換膚功能,總體效率上來說這種方案和體驗是比較好的。


          原文鏈接:https://juejin.cn/post/7282290326068641847


          主站蜘蛛池模板: 精品亚洲AV无码一区二区三区 | 日本一区二区三区不卡在线视频| 在线免费视频一区| 国产成人一区在线不卡| 加勒比无码一区二区三区| 亚洲综合av永久无码精品一区二区 | 精品无码一区二区三区爱欲九九| 精品视频一区在线观看| 精品视频一区二区三区四区| 久久国产视频一区| 国产一区二区三区夜色| 一区二区三区午夜| 日本精品一区二区久久久| 香蕉久久ac一区二区三区| 亚洲国产成人久久一区二区三区| 亚洲国产老鸭窝一区二区三区| 亲子乱av一区二区三区| 丰满人妻一区二区三区视频53| 蜜桃视频一区二区| 日韩一区二区三区精品| 一区二区三区在线|日本| 国产AV一区二区三区无码野战| 国产一区二区精品久久岳√| 一本一道波多野结衣一区| 99精品国产一区二区三区2021| 无码人妻精品一区二区三18禁| 精品国产免费一区二区三区香蕉| 国产一区二区三区在线视頻 | 国产成人av一区二区三区在线| 国产香蕉一区二区三区在线视频| 亚洲综合无码一区二区痴汉| 日韩国产免费一区二区三区| 国产精品视频一区二区猎奇| 中文字幕日韩一区二区不卡| 在线精品亚洲一区二区| 国内精自品线一区91| 视频一区二区在线播放| 国产精品主播一区二区| 国产精品熟女一区二区| 久久er99热精品一区二区 | 一区二区三区四区精品视频 |