乐趣区

关于javascript:如何优雅的实现网页多主题风格换肤功能

海阔凭鱼跃,天高任鸟飞。好久不见!我是猫力 Molly

对于网页换肤,例如最常见的深色、浅色格调曾经是很常见的一个需要了。始终以来也有很多的实现计划,这里我次要介绍一下基于 CSS variable的实现形式

简略列举下一些其它实现形式

1、把不同格调款式写到不同的类名上面,通过切换类名来实现换肤

这种形式没啥显著的长处,只是单纯的实现了此需要。反而减少了 css 款式文件代码冗余且会造成大量反复代码,款式代码不利于拓展保护,且开发效率低下

2、实现多套主题款式文件,通过 link 标签动静加载不同的款式文件

这种形式的长处大略是做到了按需加载吧,但同时也造成了须要拷贝大量反复代码来独自批改,也算是做到了款式隔离,相比上一种形式稍稍进步了一点可维护性吧

在多个款式文件切换的时候,可能会有加载提早。这时候能够思考应用 alternate 来解决

3、通过 less 或 sass 的变量形式实现

这种形式咱们能够将所有格调变量抽离进去,在款式代码中间接应用该变量,是一种比拟举荐的形式。极大进步了代码的拓展性和维护性

CSS variable 的实现形式

如图所示,目前支流浏览器都曾经反对css variable,咱们只管放心使用

CSS variable 容许咱们在 css 外面申明变量,在变量前加上两根小横线即可(–)

body {
  --foo: #000;
  --bar: #fff;
}

须要留神的是 css vars 变量申明,辨别大小写--foo--Foo 是两个不同的变量

var() 函数

应用 var()函数来读取变量

p{color:var(--foo)
}

var()函数反对第二个参数,用于示意变量的默认值,如果变量值不存在,则以默认值为准

p{color:var(--fooo, #ccc)
}

对于 var() 函数此处不做过多赘述,详情请查阅官网文档

计划落地

大抵思路:不论深色或是浅色格调,咱们都能够把它视作一个个主题。把每个主题的色彩值、盒子宽高、图片地址等抽离为一个字典对象构造。一个主题对应一个配置文件,再通过切换配置文件来实现主题格调的变动

一、和 UI 设计师沟通好各主题的色阶

一个主题对应一份配置文件,所以咱们须要提前和 UI 设计师沟通好各主题对应的色阶,字号,一些通用款式规定等

css vars变量名称是不变的,变量值随着主题的切换而产生扭转

我的 UI 共事应用的是 figma,而后我发现 figma 右侧的信息栏外面有色彩编号,正好能够应用这个来当做变量名称。在编码阶段,看到这个编号,就晓得用什么变量名了,十分不便。

如果你的 UI 共事应用的是别的设计工具,最好也是提前约定好变量名,使其大家都不便

二、将各主题色阶抽离为一个字典对象

dark.js

export default {
  '--grey900': '#EBEEF5',
  '--grey600': '#A7ABC0',
  '--grey500': '#72768D',
  '--grey400': '#5D6177',
  '--grey300': '#404759',
  '--grey200': '#2C323E',
  '--grey100': '#282B32',
  '--grey50': '#171B22',
  '--grey0': '#222730',
  ...
}  

white.js

export default {
  '--grey900': '#1F2429',
  '--grey600': '#646C73',
  '--grey500': '#8D9399',
  '--grey400': '#C3C7CB',
  '--grey300': '#E4E6E7',
  '--grey200': '#EFF0F1',
  '--grey100': '#F4F5F6',
  '--grey50': '#F8F9FA',
  '--grey0': '#FFFFFF',
  ...
}  

三、通过 js 设置 style 变量

这里咱们须要用到 document.body.style 的 api

// 设置变量
document.body.style.setProperty('--foo', '#666')

// 读取变量
document.body.style.getPropertyValue('--foo')

// 删除变量
document.body.style.removeProperty('--foo')

遍历变量字典对象,依据不同主题,给网页设置对应变量

import C from '@/utils/cssVarMap'

setCssVar (flag) {const varList = Object.entries(flag ? C.white : C.dark)
  varList.forEach(([key, val]) => {document.body.style.setProperty(key, val)
  })
}

至此,咱们曾经实现依据不同主题设置不同主题变量了,能够欢快的在款式文件外面应用css vars

这种形式操作简略,且极大的进步了代码的拓展性和维护性。之后再有别的主题,也不过是多减少一份配置文件而已,不会减少额定的副作用。

触类旁通

1、联合媒体查问

通过联合媒体查问,咱们能够实现更简单的交互场景

body {--foo: #fff}

p {color: var(--foo)
}

@media screen and (min-width: 768px) {
  body {--foo: #000}
}

2、联合 js 业务逻辑

在一些非凡需要场景下,咱们能够联合 js 业务逻辑,动静追加或编辑 css vars

const docStyle = document.documentElement.style;

document.addEventListener('mousemove', (e) => {docStyle.setProperty('--foo', e.clientX);
});

3、存储一些信息

既然是申明变量,那么就有存储信息的性能。咱们能够试着将一些信息存储在 css vars 外面,再通过 document.body.style.getPropertyValue('--foo') 去读取应用。不过大部分场景应该应用不到这种办法,也算是提供一种思路吧。

css vars是个潜力股,一起来开掘它更多奇妙的用法吧

感激

欢送关注我的集体公众号前端有猫腻每天给你推送陈腐的优质好文。回复“福利”即可取得我精心筹备的前端常识大礼包。愿你一路前行,眼里有光!

感兴趣的小伙伴还能够加我微信:猫力 molly 或前端交换群和泛滥优良的前端攻城狮一起交换技术,一起游玩!

退出移动版