JavaScriptによるCSS値の変更


105

JavaScriptでインラインCSS値を設定するのは簡単です。幅を変更したい場合、次のようなhtmlがあります。

<div style="width: 10px"></div>

私がする必要があるのは:

document.getElementById('id').style.width = value;

インラインスタイルシートの値が変更されます。インラインスタイルがスタイルシートをオーバーライドするため、通常これは問題ではありません。例:

<style>
   #tId {
      width: 50%;
   }
</style>

<div id="tId"></div>

このJavascriptを使用する:

document.getElementById('tId').style.width = "30%";

私は以下を得ます:

<style>
   #tId {
      width: 50%;
   }
</style>

<div id="tId" style="width: 30%";></div>

これは問題です。インライン値を変更したくないだけでなく、設定する前に幅を探した場合、

<div id="tId"></div>

返される値はNullであるため、ロジックを実行するために何かの幅を知る必要があるJavascriptがある場合(幅を特定の値ではなく1%増やします)、文字列 "50%を期待するときにNullを返します「実際には機能しません。

だから私の質問:インラインに配置されていないCSSスタイルの値があります。これらの値を取得するにはどうすればよいですか?IDを指定して、インライン値の代わりにスタイルを変更するにはどうすればよいですか?


投稿を編集できますか?最初にいくつかの不完全な文がありますが、何を探していたのか
Jason S

私はまだあなたが尋ねていることについて少し混乱しています。1)すべての要素を一度に変更するCSS自体を変更するように求めていますか?または2)一度に1つの項目のCSSを変更するには?
マイク

実際の質問についても混乱しています。オブジェクトの現在のスタイルは、タグの 'style'属性と同じであるとは限りません。
MattJ

わかりやすくするために編集します。インラインCSSを設定したくありません。スタイルの幅を増減できるようにしたいのですが。私が探しているものの完全な例を使って編集します。
コルティン

回答:


90

わかりました、グローバルCSSを変更して、ペティキュラスタイルのすべての要素を一度に効率的に変更したいようです。私は最近、これを自分で行う方法をShawn Olsonチュートリアルから学びました。ここで彼のコードを直接参照できます

ここに要約があります:

スタイルシートはから取得できますdocument.styleSheets。これにより、実際にはページ内のすべてのスタイルシートの配列が返されますが、document.styleSheets[styleIndex].hrefプロパティを介してどのスタイルシートを使用しているかを確認できます。編集するスタイルシートを見つけたら、ルールの配列を取得する必要があります。これはIEでは「ルール」と呼ばれ、他のほとんどのブラウザでは「cssRules」と呼ばれます。現在使用しているCSSRule確認する方法は、selectorTextプロパティです。作業コードは次のようになります。

var cssRuleCode = document.all ? 'rules' : 'cssRules'; //account for IE and FF
var rule = document.styleSheets[styleIndex][cssRuleCode][ruleIndex];
var selector = rule.selectorText;  //maybe '#tId'
var value = rule.value;            //both selectorText and value are settable.

これがどのように機能するかを教えてください。エラーが発生した場合はコメントしてください。


1
100要素以上の要素がある場合、CSSをこのように変更する方がはるかに高速です。たとえば、テーブルの特定の部分のすべてのセルを一度に変更するとします。
EdH 2013

5
rule.valueFF 20にはありません。rule.styleただし、設定可能で、のように動作しelement.styleます。Cf. https://developer.mozilla.org/en-US/docs/DOM/CSSStyleRulerule.type == rule.STYLE_RULEにアクセスする前に確認することもお勧めしrule.selectorTextます。
クリスチャンアイシンガー、2013

1
それは素晴らしかった!私は画像のトランジションに取り組んでいましたが、大きな画像をスライスするために36の別々のURIに入れ始めると、CSSは本当に遅くなります。これは、私のスクリプトから膨大なオーバーヘッドを取りました。ありがとう!
Jason Maggard 2016


document.styleSheets[styleIndex].cssRules.[ruleIndex].style = {'color':'red', 'background-color':'green'};私のために働いた、ありがとう!
Pavel

43

お願いします!w3(http://www.quirksmode.org/dom/w3c_css.html)に質問してください!または、実際には5時間かかりました...しかし、ここにあります!

function css(selector, property, value) {
    for (var i=0; i<document.styleSheets.length;i++) {//Loop through all styles
        //Try add rule
        try { document.styleSheets[i].insertRule(selector+ ' {'+property+':'+value+'}', document.styleSheets[i].cssRules.length);
        } catch(err) {try { document.styleSheets[i].addRule(selector, property+':'+value);} catch(err) {}}//IE
    }
}

関数は本当に使いやすいです。例:

<div id="box" class="boxes" onclick="css('#box', 'color', 'red')">Click Me!</div>
Or:
<div class="boxes" onmouseover="css('.boxes', 'color', 'green')">Mouseover Me!</div>
Or:
<div class="boxes" onclick="css('body', 'border', '1px solid #3cc')">Click Me!</div>

ああ..


編集: @ user21820がその回答で説明したように、ページ上のすべてのスタイルシートを変更することは少し不要かもしれません。次のスクリプトはIE5.5と最新のGoogle Chromeで動作し、上記のcss()関数のみを追加します。

(function (scope) {
    // Create a new stylesheet in the bottom
    // of <head>, where the css rules will go
    var style = document.createElement('style');
    document.head.appendChild(style);
    var stylesheet = style.sheet;
    scope.css = function (selector, property, value) {
        // Append the rule (Major browsers)
        try { stylesheet.insertRule(selector+' {'+property+':'+value+'}', stylesheet.cssRules.length);
        } catch(err) {try { stylesheet.addRule(selector, property+':'+value); // (pre IE9)
        } catch(err) {console.log("Couldn't add style");}} // (alien browsers)
    }
})(window);

非常に簡単な実装。ありがとう
カレブアンダーソン

1
私の答えのように新しく作成された単一のスタイルシートではなく、すべてのスタイルシートを変更する理由はありますか?
user21820

非常に素晴らしい実装。どうぞよろしくお願いします。
Jason Maggard 2016

1
@ user21820、おそらくそうではありません。私は本当に安全な側にいたかったと思います。.回答が最終的に更新されました、あなたに敬意を表します:)
Leonard Pauli

10

回答のコードを集めて、FF 25でうまく動作しているように見えるこの関数を書きました。

function CCSStylesheetRuleStyle(stylesheet, selectorText, style, value){
  /* returns the value of the element style of the rule in the stylesheet
  *  If no value is given, reads the value
  *  If value is given, the value is changed and returned
  *  If '' (empty string) is given, erases the value.
  *  The browser will apply the default one
  *
  * string stylesheet: part of the .css name to be recognized, e.g. 'default'
  * string selectorText: css selector, e.g. '#myId', '.myClass', 'thead td'
  * string style: camelCase element style, e.g. 'fontSize'
  * string value optionnal : the new value
  */
  var CCSstyle = undefined, rules;
  for(var m in document.styleSheets){
    if(document.styleSheets[m].href.indexOf(stylesheet) != -1){
     rules = document.styleSheets[m][document.all ? 'rules' : 'cssRules'];
     for(var n in rules){
       if(rules[n].selectorText == selectorText){
         CCSstyle = rules[n].style;
         break;
       }
     }
     break;
    }
  }
  if(value == undefined)
    return CCSstyle[style]
  else
    return CCSstyle[style] = value
}

これは、ブラウザーで理解されていなくても、JSで使用されるcssに値を配置する方法です。たとえば、スクロールされたテーブルのtbodyのmaxHeight。

電話:

CCSStylesheetRuleStyle('default', "#mydiv", "height");

CCSStylesheetRuleStyle('default', "#mydiv", "color", "#EEE");


1
スタイルがHTMLページに埋め込まれている場合、document.styleSheets[m].hrefnullになり失敗します。
JCM 2017

4

他のソリューションがドキュメントのスタイルシートのリスト全体を処理する理由がわかりません。これを行うと、各スタイルシートに新しいエントリが作成され、効率が悪くなります。代わりに、新しいスタイルシートを追加して、そこに目的のCSSルールを追加するだけです。

style=document.createElement('style');
document.head.appendChild(style);
stylesheet=style.sheet;
function css(selector,property,value)
{
    try{ stylesheet.insertRule(selector+' {'+property+':'+value+'}',stylesheet.cssRules.length); }
    catch(err){}
}

プロパティの値に「!important」を追加することで、要素に直接設定されたインラインスタイルでもオーバーライドできます。


1
より複雑なバージョンについては、developer.mozilla.org / en-US / docs / Web / API / CSSStyleSheet /…を参照てください。
user21820

1
とても本当です。.insertRuleが失敗した場合は、必ず.addRule(selector、property + ':' + value)を使用してください(IE9より前のサポートの場合)。
Leonard Pauli

3

コメントするのに十分な担当者がいないので、回答をフォーマットしますが、それは問題の問題のデモンストレーションにすぎません。

要素のスタイルがスタイルシートで定義されている場合、getElementById( "someElement")。styleからは見えないようです

このコードは問題を示しています... jsFiddleの下からのコード

テスト2では、最初の呼び出しで項目の残りの値が定義されていないため、単純なトグルであるはずのものが乱れます。私の用途では、重要なスタイル値をインラインで定義しますが、スタイルシートの目的を部分的に損なうようです。

これがページコードです...

<html>
  <head>
    <style type="text/css">
      #test2a{
        position: absolute;
        left: 0px;
        width: 50px;
        height: 50px;
        background-color: green;
        border: 4px solid black;
      }
      #test2b{
        position: absolute;
        left: 55px;
        width: 50px;
        height: 50px;
        background-color: yellow;
        margin: 4px;
      }
    </style>
  </head>
  <body>

  <!-- test1 -->
    Swap left positions function with styles defined inline.
    <a href="javascript:test1();">Test 1</a><br>
    <div class="container">
      <div id="test1a" style="position: absolute;left: 0px;width: 50px; height: 50px;background-color: green;border: 4px solid black;"></div>
      <div id="test1b" style="position: absolute;left: 55px;width: 50px; height: 50px;background-color: yellow;margin: 4px;"></div>
    </div>
    <script type="text/javascript">
     function test1(){
       var a = document.getElementById("test1a");
       var b = document.getElementById("test1b");
       alert(a.style.left + " - " + b.style.left);
       a.style.left = (a.style.left == "0px")? "55px" : "0px";
       b.style.left = (b.style.left == "0px")? "55px" : "0px";
     }
    </script>
  <!-- end test 1 -->

  <!-- test2 -->
    <div id="moveDownThePage" style="position: relative;top: 70px;">
    Identical function with styles defined in stylesheet.
    <a href="javascript:test2();">Test 2</a><br>
    <div class="container">
      <div id="test2a"></div>
      <div id="test2b"></div>
    </div>
    </div>
    <script type="text/javascript">
     function test2(){
       var a = document.getElementById("test2a");
       var b = document.getElementById("test2b");
       alert(a.style.left + " - " + b.style.left);
       a.style.left = (a.style.left == "0px")? "55px" : "0px";
       b.style.left = (b.style.left == "0px")? "55px" : "0px";
     }
    </script>
  <!-- end test 2 -->

  </body>
</html>

これが問題の解明に役立つことを願っています。

スキップ


2

任意の要素の「計算された」スタイルを取得できます。

IEは "currentStyle"と呼ばれるものを使用し、Firefox(および他の "標準準拠"ブラウザーを想定)は "defaultView.getComputedStyle"を使用します。

これを行うには、クロスブラウザー関数を記述するか、プロトタイプやjQuery(プロトタイプjavascriptファイルで「getStyle」、jquery javascriptファイルで「curCss」を検索)などの優れたJavascriptフレームワークを使用する必要があります。

つまり、高さまたは幅が必要な場合は、おそらくelement.offsetHeightおよびelement.offsetWidthを使用する必要があります。

返される値はNullなので、ロジックを実行するために何かの幅を知る必要があるJavascriptがある場合(特定の値ではなく、幅を1%増やします)

問題の要素にインラインスタイルを追加すると、それは「デフォルト」値として機能し、要素のインラインスタイルプロパティであるため、ページの読み込み時にJavascriptで読み取ることができます。

<div style="width:50%">....</div>


0

私はこれの実用的な使用を見たことがありませんが、おそらくDOMスタイルシートを検討する必要があります。しかし、正直言ってそれはやり過ぎだと思います。

要素の幅と高さを取得するだけの場合は、寸法の適用元に関係なく、element.offsetWidthおよびを使用しelement.offsetHeightます。


私の使用:<style> #tid {width:10%; } </ style> <div id = 'tid' onclick = "increase( 'tid')"> </ div>を増やすと、幅が100%未満かどうかがチェックされ、100%を超える場合は1%増えます。document.getElementById.style.widthは、インライン値がないためnullを返します。DOMスタイルシートより簡単な方法はありますか?
コルティン

0

おそらくこれを試してください:

function CCSStylesheetRuleStyle(stylesheet, selectorText, style, value){
  var CCSstyle = undefined, rules;
  for(var m in document.styleSheets){
    if(document.styleSheets[m].href.indexOf(stylesheet) != -1){
     rules = document.styleSheets[m][document.all ? 'rules' : 'cssRules'];
     for(var n in rules){
       if(rules[n].selectorText == selectorText){
         CCSstyle = rules[n].style;
         break;
       }
     }
     break;
    }
  }
  if(value == undefined)
    return CCSstyle[style]
  else
    return CCSstyle[style] = value
}
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.