JavaScriptに関するお知らせ

SINCE2019
>
【JS】CSS変数の全ての値を取得しJSオブジェクトに変換-1

【JS】CSS変数の全ての値を取得しJSオブジェクトに変換-1


こんにちは!今日はCSS変数の取得についてです。

任意のCSS変数の値を取得

はじめに任意の値を取得してみます。

こっちはCSS変数の名前が分かっていれば取得は簡単です:) 例えば富士山(3776m)の高さを取得する時は...

:root {
  --mount-fuji: 3776000mm;
}
const height = document.documentElement.style.getPropertyValue('--mount-fuji')

console.log(height) // 3776000mm

このようにシンプルに書けます。富士山の高さをミリで書くってなかなかないわね

なおCSS変数は基本的には:rootで宣言するため、今回のコードもそれを前提にしています。

複数のCSS変数の値を取得

では、複数のCSS変数を取得したい場合はどうでしょう?

:root {
  --mount-fuji: 3776000mm;
  --everest: 8848000mm;
}

これを配列で取得すると...

const getCSSValues = keys =>
  keys.map(key => document.documentElement.style.getPropertyValue(key))

const heightList = getCSSValues(['--mount-fuji', '--everest'])

console.dir(heightList)
// 3776000mm
// 8848000mm

できなくもないですが、変更に非常に弱い:( 変数を変更、追加する時に絶対ミスる。

「getPropertyAll」みたいなメソッドがあれば楽なんだけど...

全てのCSS変数の値を取得(getPropertyAll)

というわけでgetPropertyAllを1つの関数で作ってみました。

:root {
  --mount-fuji: 3776000mm;
  --everest: 8848000mm;
}
const getPropertyAll = () =>
  [...document.styleSheets].reduce(
    (pre, cur) =>
      pre ||
      ([...cur.cssRules].some(sheet => sheet.selectorText === ':root')
        ? [...cur.cssRules].reduce(
            (pre, cur) =>
              pre ||
              (cur.selectorText === ':root'
                ? cur.cssText.split(/:root\s*{|;|}/).reduce(
                    (pre, cur) =>
                      cur.trim()
                        ? {
                            ...pre,
                            [cur
                              .match(/.*?(?=:)/)[0]
                              .replace(/-/g, '_')
                              .trim()]: cur.match(/(?<=:)(.*)/)[0].trim(),
                          }
                        : pre,
                    {},
                  )
                : pre),
            null,
          )
        : pre),
    null,
  )

console.dir(getPropertyAll())
// {
//  __mount_fuji: 3776000mm,
//  __everest: 8848000mm,
// }

なお、JSでは変数にハイフンを使えないのでCSS変数--foo-barを__foo_barにしています。

また、[... hogehoge]みたいな記述に関してはこちらの記事をご覧ください。

カオス

なぜ1つの関数で書こうと思ったのか。

近日中にもう少し分かりやすいコードを書きます。

最後に

そもそもCSS変数って使う?

私は使います(小声)

【追記】(2019/04/25)続き書きました:)



PREV
2019-04-22
【JS】HTMLCollectionをループ処理可能にする

NEXT
2019-04-25
【JS】CSS変数の全ての値を取得しJSオブジェクトに変換-2