Modifica delle variabili CSS con ambito utilizzando JavaScript
Ho cercato un po' su Google questo argomento e non ho trovato una soluzione ragionevole, quindi ho pensato che valesse la pena scrivere un breve articolo.
Contenuto
- Il problema
- Come modificare le variabili CSS all'interno di :root
- Come modificare le variabili CSS con ambito
- La modifica delle variabili CSS con ambito all'interno di un Web Worker
- Creazione di una scorciatoia
- Il progetto neo.mjs
- Fuori tema, ma incredibile: cosa pensa ChatGPT di neo?
Nel caso in cui lavori con più temi, sembra un caso d'uso comune non inserire le tue variabili CSS direttamente sotto :root.
Invece, potresti usare una struttura come:root .theme-light {/*my variables*/}
Nel caso in cui desideri modificare i valori di queste variabili CSS in fase di esecuzione utilizzando JavaScript, questo può essere un po' complicato.
2. Come modificare le variabili CSS all'interno di :root
:root {
--my-color: red;
}
document.documentElement.setProperty('--my-color', 'blue');
3. Come modificare le variabili CSS con ambito
:root .theme-light {
--my-color: red;
}
:root .theme-dark {
--my-color: darkred;
}
Possiamo ad esempio applicare theme-light al viewport, utilizzare un contenitore figlio con theme-dark e all'interno di quello pulsanti di nuovo con theme-light.
Speravo in un modo elegante per modificare le variabili CSS anche per questo caso d'uso. Non l'ho trovato. COSÌ:
/**
* @param {Object} data
* @param {String} data.key
* @param {String} [data.priority] optionally pass 'important'
* @param {String} data.theme
* @param {String} data.value
*/
function setCssVariable(data) {
let key = data.key,
rule, sheet;
if (!key.startsWith('--')) {
key = '--' + key;
}
for (sheet of document.styleSheets) {
if (sheet.href.includes(data.theme)) {
for (rule of sheet.cssRules) {
if (rule.constructor.name === 'CSSStyleRule') {
if (rule.style.getPropertyValue(key) !== '') {
rule.style.setProperty(key, data.value, data.priority);
return true;
}
}
}
}
}
return false;
}
setCssVariable({
key : 'my-color',
theme: 'theme-light',
value: 'blue'
});
Stiamo iterando su tutti i fogli di stile del documento. Supponendo che l'URL del tuo file CSS contenga il nome del tuo tema, puoi limitare la quantità di controlli da esso.
In caso contrario, puoi controllare l' selectorTextinterno dell'anello interno (più costoso):
Per il caso d'uso neo, ogni file del tema ha solo una CSSStyleRule, quindi il ciclo interno non è così costoso come potrebbe sembrare a prima vista.
I valori di proprietà non esistenti restituiscono una stringa vuota (interessante :)), quindi possiamo controllarla per identificare quale CSSRule contiene la variabile che vogliamo modificare.
Accedendo nuovamente alla proprietà rule.style otteniamo:
e abbiamo finito.
Puoi utilizzare questa tecnica all'interno della tua app Angular, React o qualsiasi altra tecnologia mainstream. Le prossime sezioni vanno oltre questo.
4. Modifica delle variabili CSS con ambito all'interno di un Web Worker
src/main/addon/Stylesheet.mjs (thread principale)
class Stylesheet extends Base {
static getConfig() {return {
className: 'Neo.main.addon.Stylesheet',
remote: {
app: [
'setCssVariable'
]
}
}}
setCssVariable(data) {
// ...
}
}
Se guardi da vicino la console noterai la casella blu → l'ambito è impostato su un Web Worker e possiamo semplicemente chiamare il metodo come una promessa all'interno dello stesso spazio dei nomi altrimenti vuoto.
5. Creazione di un collegamento
src/worker/App.mjs (fuori dal thread principale)
class App extends Base {
construct(config) {
super.construct(config);
// convenience shortcut
Neo.setCssVariable = this.setCssVariable.bind(this);
}
setCssVariable(data) {
let addon = Neo.main?.addon?.Stylesheet,
theme = Neo.config.themes?.[0];
if (!addon) {
return Promise.reject('Neo.main.addon.Stylesheet not imported');
} else {
if (theme.startsWith('neo-')) {
theme = theme.substring(4);
}
return addon.setCssVariable({theme, ...data});
}
}
}
dall'interno di un Web Worker.
6. Il progetto neo.mjs
"Un lavoratore dell'applicazione è l'attore principale" o "fuori dal filo conduttore" non sono più finzione, ma funzionano in modo molto stabile ed estremamente veloce:
neo ha già raggiunto la v4.8.2 con oltre 15.000 commit all'interno dell'ecosistema. Potresti aver perso migliaia dal mio ultimo post sul blog.
Nel caso in cui non hai esaminato i vantaggi di prestazioni, scalabilità ed estensibilità, potresti voler recuperare il ritardo con l'argomento dei frontend multithread di nuova generazione.
Come spoiler: Max Rahder è nel bel mezzo dell'insegnamento del primo neo training professionale per 20 studenti. Una volta terminato, dovremmo avere abbastanza contenuti per lanciare finalmente la sezione di apprendimento mancante.
Se sei interessato a ottenere un accesso anticipato, inviaci un ping su Slack:
7. Fuori tema, ma incredibile: cosa ne pensa ChatGPT di neo?
Cordiali saluti e buona programmazione,
Tobias

![Che cos'è un elenco collegato, comunque? [Parte 1]](https://post.nghiatu.com/assets/images/m/max/724/1*Xokk6XOjWyIGCBujkJsCzQ.jpeg)



































