当前位置: 首页 > news >正文

前端网站动态主题色解决方案

动态主题色替换分两种:UI 组件库主题色替换系统主题色替换

组件库 UI 动态主题替换现阶段只在 Element-UI 和 Vant-UI 测试过,根据排查这种方案应该适用于所有类似的动态主题色替换场景。

1. UI 组件库主题色替换

在进入到这一部分之前,需要了解PC和移动端项目在本地或者在正式运行环境运行的情况下,项目文件是不可以写的。

首先,通过 XHR 请求获取到远程原始的 css 资源。拿到原始数据之后,我们存在在某个变量中,便于后期处理。

 /**
   * 获取远程 css 内容,便于二次修改 css 样式
   * @param {url} string css 存放地址(记得解决跨域问题)
   * @param {variable} string 读取 css 内容之后,赋予的值的变量名
*/
getCSSString (url, variable) {
  return new Promise(resolve => {
    const xhr = new XMLHttpRequest()
    xhr.onreadystatechange = () => {
      if (xhr.readyState === 4 && xhr.status === 200) {
        this[variable] = xhr.responseText.replace(/@font-face{[^}]+}/, '')
        resolve()
      }
    }
    xhr.open('GET', url)
    xhr.send()
  })
}

然后,我们对我们的通过方法处理我们需要转换成的主题颜色生成themeCluster。同时,我们以相同的方式处理原始的主题颜色生成originalCluster。最后,我们需要通过正则的方式,用新的主题色取代原始的主题色,输出处理后的数据,得到处理完的数据后,将数据动态的写入到header头部。

由此一个替换组件主题色的流程结束。涉及的代码如下:

/**
 * 动态往头部插入 style 标签
 * @param {variable} string 存在的变量
 * @param {id} string 用于标记 style attr
 * @param {color} 要替换的主题颜色
*/
getHandler (variable, id, color) {
  return () => {
    const themeCluster = this.getThemeCluster(color.replace('#', ''))
    const originalCluster = this.getThemeCluster(ORIGINAL_THEME.replace('#', ''))
    const newStyle = this.updateStyle(this[variable], originalCluster, themeCluster)
    let styleTag = document.getElementById(id)
    if (!styleTag) {
      styleTag = document.createElement('style')
      styleTag.setAttribute('id', id)
      document.head.appendChild(styleTag)
    }
    styleTag.innerText = newStyle
  }
}

处理新旧主题色的函数:

getThemeCluster(theme) {
  const tintColor = (color, tint) => {
    let red = parseInt(color.slice(0, 2), 16)
    let green = parseInt(color.slice(2, 4), 16)
    let blue = parseInt(color.slice(4, 6), 16)
    if (tint === 0) { // when primary color is in its rgb space
      return [red, green, blue].join(',')
    } else {
      red += Math.round(tint * (255 - red))
      green += Math.round(tint * (255 - green))
      blue += Math.round(tint * (255 - blue))
      red = red.toString(16)
      green = green.toString(16)
      blue = blue.toString(16)
      return `#${red}${green}${blue}`
    }
  }

  const shadeColor = (color, shade) => {
    let red = parseInt(color.slice(0, 2), 16)
    let green = parseInt(color.slice(2, 4), 16)
    let blue = parseInt(color.slice(4, 6), 16)
    red = Math.round((1 - shade) * red)
    green = Math.round((1 - shade) * green)
    blue = Math.round((1 - shade) * blue)
    red = red.toString(16)
    green = green.toString(16)
    blue = blue.toString(16)
    return `#${red}${green}${blue}`
  }

  const clusters = [theme]

  for (let i = 0; i <= 9; i++) {
    clusters.push(tintColor(theme, Number((i / 10).toFixed(2))))
  }

  clusters.push(shadeColor(theme, 0.1))

  return clusters
},

使用replace方式通过匹配正则去将原始主题色换成新的主题色。

/**
 * 用新的 color 替换旧的 color
 * @param {*} style 
 * @param {*} oldCluster 旧 color
 * @param {*} newCluster 新 color
 */
updateStyle(style, oldCluster, newCluster) {
  let newStyle = style
  oldCluster.forEach((color, index) => {
    newStyle = newStyle.replace(new RegExp(color, 'ig'), newCluster[index])
  })
  return newStyle
}

总的代码都已经一一列举,大家感兴趣可以亲自实践一下。

🎉 有问题下方评论探讨一下。(上方代码是在 Vue2.x 版本中进行编写,大家可以根据具体的应用进行稍微改写)

2. 系统主题色替换

系统主题色替代方案,我只提供一下方案,代码就不具体写了。系统主题色可以通过后端请求,将用户变更的主题配色保存在sql中,每个用户修改的主题色有一个对应的表记录,下次访问的时候可以从表中取出。

用户访问系统,系统的主题展示根据登录用户的唯一标记来从数据库查询,没有找到用默认,找到使用数据库数据。拿到则用数据库记录,没有查到等异常情况用默认主题色。

上面就是我自己对UI 组件库主题色替换系统主题色替换的具体实现的相关介绍和具体思路,描述不清楚或者描述不对可以在下方评论。

👏 谢谢大家花时间观看,希望大家都有所收获。

— 微信公众号:全栈之鬼影重重 —
在这里插入图片描述

相关文章:

  • 用DevExpress实现基于HTMLCSS的桌面应用程序的UI(一)
  • Android OpenGL ES 3.0 PBO像素缓冲区对象
  • 腾讯T4级架构师用21个项目带你吃透379页深度学习TensorFlow实践pdf
  • Eureka服务注册发现原理
  • RK3399平台开发系列讲解(中断篇)中断控制器驱动初始化
  • 【Redis】Redis的持久化
  • LibreOJ_10010
  • 数据增强
  • 一文搞懂堆外内存(模拟内存泄漏)
  • 还在调API写所谓的AI“女友”,唠了唠了,教你基于python咱们“new”一个(深度学习)
  • Win7纯净版系统镜像64位介绍
  • Kali系统MSF模块暴力破解MySQL弱口令漏洞
  • [附源码]java毕业设计疫情环境下的酒店管理系统
  • kafka配置外网访问
  • java每一练(3)
  • Java学习----前端4
  • ABAP中 delete 语句的使用
  • cesium火箭发射,模型控制,模型动画,模型移动
  • http请求走私漏洞原理,利用,检测,防护
  • Docker学习(3)—— 将容器转化为新的镜像,并将新镜像发布到阿里云公共仓库或私有仓库
  • JSP文件上传
  • qt人员管理模块(模块化程序)功能块复制直接使用不冲突
  • [附源码]计算机毕业设计微信点餐系统Springboot程序
  • PCB入门介绍与电阻电容电感类元件的创建
  • MongoDB入门与实战-第五章-MongoDB副本集
  • [YOLOv7/YOLOv5系列改进NO.40]融入适配GPU的轻量级 G-GhostNet
  • 15吨燃煤锅炉改生物质锅炉可以吗_燃煤锅炉环保要求
  • 生物质颗粒锅炉点不着_生物质颗粒能否替代煤锅炉
  • 10吨 燃气锅炉_陕西锅炉取暖改造补贴