我在我的項(xiàng)目中使用css根變量來隨時(shí)動(dòng)態(tài)改變所有元素的顏色。
我的css看起來像
:root{
--primaryColor:aliceblue;
--secondaryColor:blue;
--errorColor:#cc2511;
}
在css中使用
.contentCss {
background-color: var(--primaryColor);
}
我可以如下訪問javascript中的變量來動(dòng)態(tài)地改變值
document.documentElement.style.setProperty('--primaryColor', 'green');
它工作正常。我想得到一個(gè)數(shù)組中的所有變量,并據(jù)此動(dòng)態(tài)改變每個(gè)變量的值。
# # #這個(gè)腳本將從域中返回所有樣式表中的根變量數(shù)組。由于CORS政策,域外樣式表不可訪問。
Array.from(document.styleSheets)
.filter(
sheet =>
sheet.href === null || sheet.href.startsWith(window.location.origin)
)
.reduce(
(acc, sheet) =>
(acc = [
...acc,
...Array.from(sheet.cssRules).reduce(
(def, rule) =>
(def =
rule.selectorText === ":root"
? [
...def,
...Array.from(rule.style).filter(name =>
name.startsWith("--")
)
]
: def),
[]
)
]),
[]
);
注意:較低順序樣式表中的root:規(guī)則將覆蓋父根規(guī)則。
# # #您可以聲明一個(gè)關(guān)聯(lián)數(shù)組,其中的鍵和它們的值作為節(jié)點(diǎn)屬性,然后使用一個(gè)函數(shù)來設(shè)置您的主題:
var primaryColor = document.documentElement.style.getPropertyValue('--primaryColor');
var secondaryColor = document.documentElement.style.getPropertyValue('--secondaryColor');
var errorColor = document.documentElement.style.getPropertyValue('--errorColor');
var themeColors = {}
themeColors["--primaryColor"] = primaryColor;
themeColors["--secondaryColor"] = secondaryColor;
themeColors["--errorColor"] = errorColor;
function setTheme(theme) {
for (key in theme) {
let color = theme[key];
document.documentElement.style.setProperty(key, color);
}
}
我使用Atom和Bootstrap的一個(gè)工作示例:
var backgroundColor = document.documentElement.style.getPropertyValue('--blue');
backgroundColor = "#dc3545";
function setTheme(theme) {
for (key in theme) {
let color = theme[key];
document.documentElement.style.setProperty(key, color);
}
}
var theme = {}
theme["--blue"] = backgroundColor;
setTheme(theme);
>>編輯& lt& lt
Nadeem在下面的評(píng)論中更好地澄清了這個(gè)問題,但不幸的是,我已經(jīng)了解到:root可以通過get Window.getComputedStyle()訪問,但這不會(huì)返回CSS變量聲明。
解決這個(gè)問題的一個(gè)辦法是讀取css文件,解析其中的變量,并將它們填充到一個(gè)關(guān)聯(lián)數(shù)組中,但即使這樣也假設(shè)您知道從哪里獲取css文件...
//an associative array that will hold our values
var cssVars = {};
var request = new XMLHttpRequest();
request.open('GET', './css/style.css', true);
request.onload = function() {
if (request.status >= 200 && request.status < 400) {
//Get all CSS Variables in the document
var matches = request.responseText.match(/(--)\w.+;/gi);
//Get all CSS Variables in the document
for(let match in matches) {
var property = matches[match];
//split the Variable name from its value
let splitprop = property.split(":")
//turn the value into a string
let value = splitprop[1].toString()
cssVars[splitprop[0]] = value.slice(0, -1); //remove ;
}
// console.log(cssVars);
// > Object {--primaryColor: "aliceblue", --secondaryColor: "blue", --errorColor: "#cc2511"}
// console.log(Object.keys(cssVars));
// > ["--primaryColor", "--secondaryColor", "--errorColor" ]
setTheme(cssVars)
} else {
// We reached our target server, but it returned an error
}
};
request.onerror = function() {
console.log("There was a connection error");
};
request.send();
function setTheme(theme) {
var keys = Object.keys(theme)
for (key in keys) {
let prop = keys[key]
let color = theme[keys[key]];
console.log(prop, color);
// --primaryColor aliceblue etc...
}
}
# # #我今天需要一個(gè)類似的解決方案。在codepen上有一個(gè)簡(jiǎn)單的例子。
// could pass in an array of specific stylesheets for optimization
function getAllCSSVariableNames(styleSheets = document.styleSheets){
var cssVars = [];
// loop each stylesheet
for(var i = 0; i < styleSheets.length; i++){
// loop stylesheet's cssRules
try{ // try/catch used because 'hasOwnProperty' doesn't work
for( var j = 0; j < styleSheets[i].cssRules.length; j++){
try{
// loop stylesheet's cssRules' style (property names)
for(var k = 0; k < styleSheets[i].cssRules[j].style.length; k++){
let name = styleSheets[i].cssRules[j].style[k];
// test name for css variable signiture and uniqueness
if(name.startsWith('--') && cssVars.indexOf(name) == -1){
cssVars.push(name);
}
}
} catch (error) {}
}
} catch (error) {}
}
return cssVars;
}
function getElementCSSVariables (allCSSVars, element = document.body, pseudo){
var elStyles = window.getComputedStyle(element, pseudo);
var cssVars = {};
for(var i = 0; i < allCSSVars.length; i++){
let key = allCSSVars[i];
let value = elStyles.getPropertyValue(key)
if(value){cssVars[key] = value;}
}
return cssVars;
}
var cssVars = getAllCSSVariableNames();
console.log(':root variables', getElementCSSVariables(cssVars, document.documentElement));
# # #如果你知道所有的變量都將放在:root中,并且它是你的第一個(gè)CSS文件中的第一個(gè)聲明,你可以嘗試這樣做,你將得到一個(gè)對(duì)象中的所有變量:
var declaration = document.styleSheets[0].cssRules[0];
var allVar = declaration.style.cssText.split(";");
var result = {}
for (var i = 0; i < allVar.length; i++) {
var a = allVar[i].split(':');
if (a[0] !== "")
result[a[0].trim()] = a[1].trim();
}
console.log(result);
var keys = Object.keys(result);
console.log(keys);
//we change the first variable
document.documentElement.style.setProperty(keys[0], 'green');
//we change the variable --secondary-color
document.documentElement.style.setProperty(keys[keys.indexOf("--secondary-color")], 'red');
:root {
--primary-color: aliceblue;
--secondary-color: blue;
--error-color: #cc2511
}
p {
font-size: 25px;
color: var(--primary-color);
border:1px solid var(--secondary-color)
}
<p>Some text</p>
# # #這是typescript中的另一個(gè),我繼續(xù)了RLoniello提到的工作。它還將其輸出為JS對(duì)象,即converts-font-family:& quot;Verdana & quot致font family:& quot;Verdana & quot。
const CssKeyToJsKey = (key: string) =>
key.replace('--', '').replace(/-./g, (x) => x.toUpperCase()[1]);
const getAllCSSVariableNames = (styleSheets: StyleSheetList = document.styleSheets) => {
const cssVars = [];
Array.from(styleSheets).forEach((styleSheet) => {
Array.from(styleSheet.cssRules).forEach((rule) => {
if (!rule || !rule['style']) {
return;
}
Array.from(rule['style']).forEach((style: string) => {
if (style.startsWith('--') && cssVars.indexOf(style) == -1) {
cssVars.push(style);
}
});
});
});
return cssVars;
};
const getElementCSSVariables = (
allCSSVars: Array<string>,
element: HTMLElement = document.body,
pseudo: string | undefined = ''
) => {
const elStyles = window.getComputedStyle(element, pseudo);
const cssVars = {};
allCSSVars.forEach((key) => {
const value = elStyles.getPropertyValue(key);
if (value) {
cssVars[CssKeyToJsKey(key)] = value;
}
});
return cssVars;
};
export const getAllCSSVariables = (): Record<string, string> => {
const cssVars = getAllCSSVariableNames();
return getElementCSSVariables(cssVars, document.documentElement);
};
# # #映射到命名對(duì)象,而不使用。getComputedStyle()
/* Retrieve all --root CSS variables
* rules into a named Object
* Without using getComputedStyle (read string only)
*/
console.log(
[...document.styleSheets[0].rules]
.map(a => a.cssText.split(" ")[0] === ":root" ?
a.cssText.split("{")[1].split("}")[0].split(";") : null)
.filter(a => a !== null)[0]
.map((a) => a.split(": "))
.filter(a => a[0] !== " ")
.reduce((a, v) => ({ ...a, [v[0].slice(1)] : v[1] }), {})
)
:root {
--gold: hsl(48,100%,50%);
--gold-lighter: hsl(48,22%,30%);
--gold-darker: hsl(45,100%,47%);
--silver: hsl(210,6%,72%);
--silver-lighter: hsl(0,0%,26%);
--silver-darker: hsl(210,3%,61%);
--bronze: hsl(28,38%,67%);
--bronze-lighter: hsl(28,13%,27%);
--bronze-darker: hsl(28,31%,52%);
}
# # #這里有一個(gè)函數(shù)方法來獲取all :root CSS變量,如果您使用更嚴(yán)格的TypeScript配置,這些變量不會(huì)引發(fā)類型錯(cuò)誤:
const rootCssVariables: string[] = Array.from(document.styleSheets)
.flatMap((styleSheet: CSSStyleSheet) => Array.from(styleSheet.cssRules))
.filter(
(cssRule: CSSRule): cssRule is CSSStyleRule =>
cssRule instanceof CSSStyleRule && cssRule.selectorText === ':root',
)
.flatMap((cssRule: CSSStyleRule) => Array.from(cssRule.style))
.filter((style: string) => style.startsWith('--'))
console.log(rootCssVariables)
// e.g. ['--background-color', '--text-color', etc...]