[Javascript] ページ内のStyleSheetを読み書きするスニペット

とあるプログラミング作業をしている時に、cssファイルに書かれた値を取得したいという場面に遭遇しました。 cssデータは、styleタグとlinkタグでそれぞれ設置できますが、elementに直接かかれたproperty値じゃないとなかなか取得するのが面倒くさいので、 ページ内のStyleSheetをコントロールするclassを作って公開しておきます。

ソースコード

css.js

/** * # options * // cssの値をセットする場合 * set_css(selector , property , value) * * // cssの値を取得する場合 * get_css(selector , property) */ export class Css{ static set_css(selector , property , value){ const rule = Css.get_last_rule(selector) if(rule){ rule.style.setProperty(property , value , '') } else{ Css.create_rule(selector , property , value) } } static get_last_rule(selector){ const rules = Css.get_rules(selector) return rules && rules.length ? rules[rules.length-1] : null } static create_rule(selector , property , value){ const stylesheet = Css.get_last_stylesheet() || Css.create_stylesheet() stylesheet.insertRule(`${selector}{${property}:${value}}` , 0) } static get_last_stylesheet(){ const stylesheets = Css.get_stylesheets() return stylesheets && stylesheets.length ? stylesheets[stylesheets.length-1] : null } static create_stylesheet(){ const style = document.createElement('style') document.querySelector('head').appendChild(style) return Css.get_last_stylesheet() } static get_ss(selector , property){ const styleSheets = Array.from(document.styleSheets).filter((styleSheet) => !styleSheet.href || styleSheet.href.startsWith(window.location.origin)) let value = null for(const ss of styleSheets){ if(!ss.cssRules){continue} for(const cssRule of ss.cssRules){ if(!cssRule.styleSheet || !cssRule.styleSheet.cssRules){continue} for(const rule of cssRule.styleSheet.cssRules){ if(rule.selectorText !== selector){continue} value = rule.style[property] } } } return value; } static get_css(selector , property){ const rules = Css.get_rules(selector) let value = null for(const rule of rules){ value = rule.style.getPropertyValue(property) || value } return value } static get_stylesheets(){ return Array.from(document.styleSheets).filter((styleSheet) => !styleSheet.href || styleSheet.href.startsWith(window.location.origin)) } static get_rules(selector){ const styleSheets = Css.get_stylesheets() let arr = [] for(const ss of styleSheets){ if(!ss.cssRules){continue} const res = this.get_rule(ss.cssRules , selector) if(!res || !res.length){continue} arr = arr.concat(res) } return arr; } static get_rule(rules , selector){ if(!rules){return} let arr = [] for(const rule of rules){ if(rule.selectorText === selector){ arr.push(rule) } if(rule.styleSheet && rule.styleSheet.cssRules){ const res = Css.get_rule(rule.styleSheet.cssRules , selector) if(!res || !res.length){continue} arr = arr.concat(res) } } return arr; } }

使い方

moduleタイプで読み込んで、次のようにすると、cssの値の読み書きができるようになります。

css値の読み取り

Css.get_css("要素のセレクター" , "値を取得したいcssプロパティ")

css値の書き込み

Css.set_css("要素のセレクター" , "セットしたいcssプロパティ" , "セットしたい値") ※存在しないプロパティでも、追記することができます。

サンプル

index.html

<link rel='stylesheet' href='style.css'/> <h1>css-control</h1> <div id='sample'></div> <div id='sample2'></div> <style> #sample{ border-style:dashed; } </style> <script type='module'> import { Css } from './css.js' // 取得 console.log(Css.get_css('#sample' , 'background-color')) console.log(Css.get_css('#sample' , 'margin-left')) console.log(Css.get_css('#sample' , 'padding-left')) console.log(Css.get_css('#sample' , 'border-style')) // 書換 Css.set_css('#sample' , 'background-color' , 'blue') Css.set_css('#sample' , 'border-width' , '4px') Css.set_css('#sample' , 'border-color' , 'black') // 追加 Css.set_css('#sample2' , 'width' , '100px') Css.set_css('#sample2' , 'height' , '100px') Css.set_css('#sample2' , 'background-color' , 'red') </script>

style.css

#sample{ width:100px; height:100px; background-color:red; padding:4px 6px 8px 10px; }

解説

値の取得について

読み込む時の、selectorは、cssに書かれている値が対象になります。 cssに掛かれていないselectorやpropertyは、nullの値が返ってきます。 複数箇所に書かれている場合は、最後の値が有効になるため、その値が取得できます。

値の書き込みについて

書き込み時は、存在しないselector、propertyは、自動的に追加されます。 読み込みと同じで、複数箇所に書かれている場合は、最後にかかれている箇所が、上書きされます。