JavaScript を使用したスコープ付き CSS 変数の変更
このトピックについてかなりグーグルで検索しましたが、妥当な解決策が見つからなかったので、短い記事にする価値があるかもしれないと思いました。
コンテンツ
- 問題
- :root 内の CSS 変数を変更する方法
- スコープ付き CSS 変数を変更する方法
- Web ワーカー内からスコープ指定された CSS 変数を変更する
- ショートカットの作成
- neo.mjs プロジェクト
- 話は逸れますが、信じられないほどです。ChatGPT は neo についてどう考えていますか?
複数のテーマを使用している場合、CSS 変数を の直下に置かないの:rootが一般的な使用例のように思えます。
代わりに、次のような構造を使用することもできます。:root .theme-light {/*my variables*/}
JavaScript を使用して実行時にこれらの CSS 変数の値を変更する場合、これは少し難しい場合があります。
2. :root 内の CSS 変数を変更する方法
:root {
--my-color: red;
}
document.documentElement.setProperty('--my-color', 'blue');
3. スコープ付き CSS 変数を変更する方法
:root .theme-light {
--my-color: red;
}
:root .theme-dark {
--my-color: darkred;
}
たとえば、テーマライトをビューポートに適用し、子コンテナをテーマダークで使用し、そのコンテナ内で再びテーマライトのボタンを使用できます。
このユースケースでも CSS 変数を変更するエレガントな方法を期待していました。見つかりませんでした。それで:
/**
* @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'
});
ドキュメントのすべてのスタイルシートを反復処理しています。CSS ファイルの URL にテーマの名前が含まれていると仮定すると、それによってチェックの量を制限できます。
そうでない場合は、内側のループの内側をチェックできますselectorText(より高価です)。
neo の使用例では、各テーマ ファイルには CSSStyleRule が 1 つだけあるため、内部ループは一見したほど高価ではありません。
存在しないプロパティ値は空の文字列を返すため (興味深い :))、それをチェックして、変更したい変数がどの CSSRule に含まれているかを識別できます。
再度、rule.style プロパティにアクセスすると、次のようになります。
これで終わりです。
このテクニックは、Angular、React、またはアプリで使用する主流のテクノロジー内で使用できます。次のセクションはこれを超えた部分です。
4. Web ワーカー内からスコープ指定された CSS 変数を変更する
src/main/addon/Stylesheet.mjs (メインスレッド)
class Stylesheet extends Base {
static getConfig() {return {
className: 'Neo.main.addon.Stylesheet',
remote: {
app: [
'setCssVariable'
]
}
}}
setCssVariable(data) {
// ...
}
}
コンソールをよく見ると、青いボックスに気づくでしょう。スコープはWeb ワーカーに設定されており、同じ空の名前空間内でメソッドを Promise として呼び出すことができます。
5. ショートカットの作成
src/worker/App.mjs (メインスレッドから離れています)
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});
}
}
}
Web ワーカー内から。
6. neo.mjs プロジェクト
「アプリケーション ワーカーが主役」または「メインスレッドから外れている」ことはもはやフィクションではなく、非常に安定して非常に高速に動作します。
neo はすでに v4.8.2 に達しており、エコシステム内で 15,000 件を超えるコミットが行われています。私の前回のブログ投稿以来、何千回も見逃してしまったかもしれません。
パフォーマンス、スケーラビリティ、拡張性のメリットをまだ調べていない場合は、次世代マルチスレッド フロントエンドのトピックを参照するとよいでしょう。
ネタバレすると、マックス・ラーダーはちょうど 20 人の生徒に最初のプロフェッショナルなネオ トレーニングを教えている最中です。完了したら、不足している学習セクションを最終的に開始するのに十分なコンテンツが得られるはずです。
早期アクセスに興味がある場合は、Slack で私たちに ping してください。
7. 本題から外れましたが、信じられないほどです: ChatGPT は neo についてどう考えていますか?
よろしくお願いします。コーディングを楽しんでください、
Tobias

![とにかく、リンクリストとは何ですか?[パート1]](https://post.nghiatu.com/assets/images/m/max/724/1*Xokk6XOjWyIGCBujkJsCzQ.jpeg)



































