如何用单个函数批量修改所有:root CSS变量及自动还原初始值
问题描述
是否可以通过一个函数获取所有变量并修改每一个的值
如果只有2-4个变量很容易修改,但当变量数量达到10个或更多时操作就很繁琐。
现有实现代码如下:
var root = document.querySelector(':root'); function func() { root.style.setProperty('--r', 'brown'); root.style.setProperty('--b', 'lightblue'); root.style.setProperty('--g', 'lightgreen'); }
:root { --r: red; --b: blue; --g: green; } .text1 { color: var(--r) } .text2 { color: var(--b) } .text3 { color: var(--g) }
<div class="text1">Hello</div> <div class="text2">Bye</div> <div class="text3">World</div> <button onclick="func()">Change</button>
问题1
是否有方法可以自动(动态)获取所有变量,无需手动逐个声明变量,仅自行传入新值数组即可完成修改?
现有需要还原初始值的实现代码如下:
var root = document.querySelector(':root'); var roots = getComputedStyle(root); var re = roots.getPropertyValue('--r') var bl = roots.getPropertyValue('--b') var gr = roots.getPropertyValue('--g') function func() { root.style.setProperty('--r', 'brown'); root.style.setProperty('--b', 'lightblue'); root.style.setProperty('--g', 'lightgreen'); } function func2() { root.style.setProperty('--r', re); root.style.setProperty('--b', bl); root.style.setProperty('--g', gr); }
:root { --r: red; --b: blue; --g: green; } .text1 { color: var(--r) } .text2 { color: var(--b) } .text3 { color: var(--g) }
<div class="text1">Hello</div> <div class="text2">Bye</div> <div class="text3">World</div> <button onclick="func()">Change</button> <button onclick="func2()">Orignal</button>
问题2
如果要还原为初始值,当前需要为每个变量单独声明变量存储初始值,逐个定义。是否存在可以自动将初始值和对应变量分别存入数组的实现方案?
解决方案
可以实现自动批量读取、修改、还原CSS变量,以下是可直接使用的实现:
实现思路
- 封装初始化函数自动提取
:root下所有以--开头的自定义CSS变量和对应初始值,存为对象备用 - 封装批量修改方法,同时支持键值对对象、按原有顺序的值数组两种传参方式
- 封装还原方法,调用即可批量恢复所有变量的初始值
完整实现代码
const root = document.querySelector(':root'); const computedRoot = getComputedStyle(root); // 存储所有初始CSS变量的对象,key为变量名,value为初始值 let originCssVars = {}; // 初始化:自动扫描所有:root下的自定义CSS变量 function initCssVars() { for (let i = 0; i < computedRoot.length; i++) { const prop = computedRoot[i]; if (prop.startsWith('--')) { originCssVars[prop] = computedRoot.getPropertyValue(prop).trim(); } } } // 批量修改CSS变量 // 传参方式1:传入对象,如 {'--r': 'brown', '--b': 'lightblue'} 按需修改指定变量 // 传参方式2:传入值数组,按初始变量的顺序批量赋值,如 ['brown', 'lightblue', 'lightgreen'] function setCssVars(params) { if (Array.isArray(params)) { const varKeys = Object.keys(originCssVars); params.forEach((val, index) => { if (varKeys[index]) root.style.setProperty(varKeys[index], val); }) } else { Object.entries(params).forEach(([key, val]) => { root.style.setProperty(key, val); }) } } // 一键还原所有CSS变量为初始值 function resetCssVars() { Object.entries(originCssVars).forEach(([key, val]) => { root.style.setProperty(key, val); }) } // 页面加载完成后自动初始化变量 window.addEventListener('load', initCssVars);
使用时直接替换原有JS逻辑即可,HTML部分可以简化为:
<div class="text1">Hello</div> <div class="text2">Bye</div> <div class="text3">World</div> <button onclick="setCssVars(['brown', 'lightblue', 'lightgreen'])">Change</button> <button onclick="resetCssVars()">Original</button>
补充说明
- 后续新增CSS变量不需要修改JS逻辑,初始化函数会自动识别所有
--开头的自定义变量 - 数组传参的顺序和CSS里定义变量的顺序完全一致,按顺序填值即可
- 只需要修改部分变量时,用对象传参的方式更灵活,不需要的变量不用传入
内容的提问来源于stack exchange,提问作者Yupma
相关产品推荐
相关产品推荐

