4441


以下のHTMLとCSSがあるとき、Javascriptで `#FF0000` を `#0000FF` に変更するには  
すべての要素を繰り返し処理で回し、さらにcolorやborder-color、background-colorの  
一つ一つの要素の中を覗いて書き換える方法しか思いつかないのですが、もうすこし  
効率の良い方法はありますか？

また、`:after` や `:before` で定義した色については差し替え不能だと思うのですが、可能ですか？

追記：  
JavascriptでDOMのクラスを書き換えることで実現する方法が紹介されましたが  
そうすると置換したい色の数だけCSSの定義を増やさなければならなくなるため  
sassを利用したスマートな解決方法などもございましたら  
是非教えていただきたいです。

* * *

**HTML**

[code]

    <h1>hoge</h1>
    <p>piyo</p>
    <div>fuga</div>
    <span>hena</span>
    
[/code]

**CSS**

[code]

    h1 {
      background: #FF0000;
    }
    
    p {
      color: #FF0000;
    }
    
    div {
      border: solid 1px #FF0000;
    }
    
    span:after {
      content: 'after:';
      color: #FF0000;
    }
    
[/code]


CC BY-SA 4.0
2015-01-12T11:31:36.740
4437
2020-02-25T11:50:54.227
2020-02-25T11:50:54.227
3060
5840
question
javascript css
Javascriptで特定のカラーを全て他の色に置き換えるには？


[document.StyleSheetsからスタイルシートにアクセスできますので](http://ash.jp/web/css/js_style.htm)、正規表現などでcssTextを置換すればよいかと思います。

# 実装例

[code]

    for (var i = 0; document.styleSheets.length; i++) {
        var ss = document.styleSheets[i];
        for (var j = 0; j < ss.cssRules.length; j++) {
            var r = ss.cssRules[j];
    
            r.style.cssText = r.style.cssText.replace(/rgb\(255, 0, 0\)/, '#00f');
        }
    }
    
[/code]

留意点としては以下の通りです。

  1. クロスドメインアクセスが出来ない。(Firefoxの既定の動作では)
  2. CSSテキストはブラウザによる解釈後の値になる。

特に2は実装上危険なので、styleSheetsを弄るのであればcssTextの値を入力として利用する必要のない処理にすべきだと思います。


CC BY-SA 3.0
2015-01-12T11:40:34.370
4438
2015-01-12T12:34:28.590
2020-06-17T08:14:45.997
-1
5750
4437
answer


設定した色の値自体を変えるのは面倒なので、ごくごく普通に複数CSSセレクタに対する一括指定をする方法が良いと思います。

## 方法1: CSS クラス指定での切り替え

やり方としては以下のようにします。

  1. 上書きルールセットとして CSS クラスを作成しておき、
  2. 対象になる要素全体を別の要素で囲んで、
  3. その要素に対する CSS クラス指定だけを変更

[code]

    h1 { background: #FF0000; }
    p { color: #FF0000; }
    div { border: solid 1px #FF0000; }
    span:after { content: 'after:'; color: #FF0000; }
    
    #root.red h1, #root.red p, #root.red div, #root.red span:after { color: #FF0000; }
    #root.green h1, #root.green p, #root.green div, #root.green span:after { color: #00FF00; }
    #root.blue h1, #root.blue p, #root.blue div, #root.blue span:after { color: #0000FF; }
[/code]

[code]

    <div id="root">
      <h1>hoge</h1>
      <p>piyo</p>
      <div>fuga</div>
      <span>hena</span>
    </div>
    
    <button onClick="javascript:document.getElementById('root').className='red';">red</button>
    <button onClick="javascript:document.getElementById('root').className='green';">green</button>
    <button onClick="javascript:document.getElementById('root').className='blue';">blue</button>
[/code]

もちろん、CSS を直接書き換える手段としては、
[document.StyleSheets](https://developer.mozilla.org/en-
US/docs/Web/API/document.styleSheets)
プロパティが存在していますが、ブラウザによって実装が違うので、モダンなブラウザ限定＋実証されたライブラリを通して使うという条件でないと使うのは[怖い感じがします](http://www.hunlock.com/blogs/Totally_Pwn_CSS_with_Javascript)。[）'0'（](http://www.hunlock.com/blogs/Totally_Pwn_CSS_with_Javascript)

* * *

**追記:**

そうですか・・・では、 [document.StyleSheets](https://developer.mozilla.org/en-
US/docs/Web/API/document.styleSheets) を使う例は以下になります。

## 方法2: CSS ルールを書き換える

`getCSSRule()`
関数は、[紹介した記事](http://www.hunlock.com/blogs/Totally_Pwn_CSS_with_Javascript)の物を使っています。

[code]

    function getCSSRule(ruleName, deleteFlag) { 
        ruleName = ruleName.toLowerCase(); 
        if (document.styleSheets) { 
          for (var i = 0; i < document.styleSheets.length; i++) { 
            var styleSheet = document.styleSheets[i]; 
            var ii = 0; 
            var cssRule = false; 
            do { 
              if (styleSheet.cssRules) { 
                cssRule = styleSheet.cssRules[ii]; 
              } else { 
                cssRule = styleSheet.rules[ii]; 
              } 
              if (cssRule) { 
                if (cssRule.selectorText.toLowerCase() == ruleName) { 
                  if (deleteFlag == 'delete') { 
                    if (styleSheet.cssRules) { 
                      styleSheet.deleteRule(ii); 
                    } else { 
                      styleSheet.removeRule(ii); 
                    } 
                    return true; 
                  } else { 
                    return cssRule; 
                  } 
                } 
              } 
              ii++; 
            } while (cssRule) 
          } 
        } 
        return false; 
      } 
    
    function killCSSRule(ruleName) { 
        return getCSSRule(ruleName, 'delete'); 
      } 
    
    function addCSSRule(ruleName) { 
      if (document.styleSheets) { 
        if (!getCSSRule(ruleName)) { 
          if (document.styleSheets[0].addRule) { 
            document.styleSheets[0].addRule(ruleName, null, 0); 
          } else { 
            document.styleSheets[0].insertRule(ruleName + ' { }', 0); 
          } 
        } 
      } 
      return getCSSRule(ruleName); 
    }
[/code]

[code]

    h1 { background: #FF0000; }
    div { border: solid 1px #FF0000; }
    span:after { content: 'after:'; }
    
    .coloring { color: #FF0000; }
[/code]

[code]

    <h1 class="coloring">hoge</h1>
    <p class="coloring">piyo</p>
    <div class="coloring">fuga</div>
    <span class="coloring">hena</span>
    
    <button onClick="javascript:getCSSRule('.coloring').style.color = '#FF0000';">red</button>
    <button onClick="javascript:getCSSRule('.coloring').style.color = 'green';">green</button>
    <button onClick="javascript:getCSSRule('.coloring').style.color = 'blue';">blue</button>
[/code]

自分としてはまだ怖い使い方なので、使用されるブラウザを限定しない限りは、この方法を推奨しません。


CC BY-SA 3.0
2015-01-12T12:08:12.007
4441
2015-01-12T13:01:15.767
2015-01-12T13:01:15.767
4978
4978
4437
answer


Sassで

[code]

    // .scss
    $class_names: red, green, blue;
    $class_colors: #FF0000, #00FF00, #0000FF;
    
    @each $class_name in $class_names {
      $index_key: index($class_names, $class_name);
    
      #root.#{$class_name} {
        h1, p, div, span:after {
          color: nth($class_colors, $index_key);
        }
      }
    }
    
[/code]

と書くと、以下のような .cssを出力できます。  
切り替えは他の方が書いているようにDOMのCSSクラス名の変更で行ってください。

[code]

    // .css
    #root.red h1, #root.red p, #root.red div, #root.red span:after { color: #FF0000; }
    #root.green h1, #root.green p, #root.green div, #root.green span:after { color: #00FF00; }
    #root.blue h1, #root.blue p, #root.blue div, #root.blue span:after { color: #0000FF; }
    
[/code]


CC BY-SA 3.0
2015-01-12T12:45:36.173
4443
2015-01-12T13:26:17.917
2015-01-12T13:26:17.917
3925
3925
4437
answer