Ändern von CSS-Werten mit Javascript

105

Es ist einfach, Inline-CSS-Werte mit Javascript festzulegen. Wenn ich die Breite ändern möchte und HTML wie folgt habe:

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

Alles was ich tun muss ist:

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

Dadurch werden die Inline-Stylesheet-Werte geändert. Normalerweise ist dies kein Problem, da der Inline-Stil das Stylesheet überschreibt. Beispiel:

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

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

Verwenden dieses Javascript:

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

Ich bekomme folgendes:

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

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

Dies ist ein Problem, da ich nicht nur keine Inline-Werte ändern möchte. Wenn ich nach der Breite suche, bevor ich sie einstelle, wenn ich:

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

Der zurückgegebene Wert ist Null. Wenn ich also Javascript habe, das die Breite von etwas wissen muss, um eine Logik auszuführen (ich erhöhe die Breite um 1%, nicht auf einen bestimmten Wert), wird Null zurückgegeben, wenn ich die Zeichenfolge "50%" erwarte "funktioniert nicht wirklich.

Meine Frage: Ich habe Werte in einem CSS-Stil, die sich nicht inline befinden. Wie kann ich diese Werte abrufen? Wie kann ich den Stil anstelle der Inline-Werte unter Angabe einer ID ändern?

Coltin
quelle
Könntest du deinen Beitrag bearbeiten? Es gibt einige unvollständige Sätze am Anfang, nicht sicher, wonach Sie gesucht haben ...
Jason S
Ich bin immer noch etwas verwirrt darüber, was Sie fragen. Bitten Sie 1), das CSS selbst zu ändern, wodurch alle Elemente gleichzeitig geändert werden? oder 2) das CSS für jeweils einen Artikel zu ändern?
Mike
Ich bin auch verwirrt, was die eigentliche Frage betrifft. Der aktuelle Stil eines Objekts muss nicht unbedingt mit dem Attribut 'style' des Tags übereinstimmen.
MattJ
Entschuldigung, ich werde es bearbeiten, um es klarer zu machen. Ich möchte kein Inline-CSS einstellen. Ich möchte die Breite des Stils vergrößern / verkleinern können. Ich werde mit einem vollständigen Beispiel bearbeiten, wonach ich suche.
Coltin
Codepens Antwort codepen.io/quezo/post/dynamically-updating-css
Nick Mitchell

Antworten:

90

Ok, es hört sich so an, als ob Sie das globale CSS so ändern möchten, dass alle Elemente eines peticularen Stils gleichzeitig wirksam geändert werden. Ich habe kürzlich in einem Shawn Olson-Tutorial gelernt, wie man das selbst macht . Sie können den Code direkt verweisen hier .

Hier ist die Zusammenfassung:

Sie können die Stylesheets über abrufen document.styleSheets. Dadurch wird tatsächlich ein Array aller Stylesheets auf Ihrer Seite zurückgegeben. Sie können jedoch über die document.styleSheets[styleIndex].hrefEigenschaft feststellen, auf welchem ​​Sie sich befinden . Sobald Sie das Stylesheet gefunden haben, das Sie bearbeiten möchten, müssen Sie das Array mit Regeln abrufen. Dies wird im IE als "Regeln" und in den meisten anderen Browsern als "cssRules" bezeichnet. Sie können anhand der Eigenschaft feststellen, auf welcher CSSRule Sie sich befinden selectorText. Der Arbeitscode sieht ungefähr so ​​aus:

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.

Lassen Sie mich wissen, wie dies für Sie funktioniert, und kommentieren Sie bitte, wenn Sie Fehler sehen.

Mike
quelle
1
Das Ändern von CSS auf diese Weise ist viel schneller, wenn Sie über 100 Elemente verfügen. Nehmen wir zum Beispiel an, Sie ändern alle Zellen in einem bestimmten Teil einer Tabelle gleichzeitig.
EdH
5
Ich kann nicht rule.valuein FF 20 finden . Es gibt rule.stylejedoch, die einstellbar ist und sich wie verhält element.style. Vgl. https://developer.mozilla.org/en-US/docs/DOM/CSSStyleRule . Das Überprüfen auf ist rule.type == rule.STYLE_RULEmöglicherweise auch eine gute Idee, bevor Sie darauf zugreifen rule.selectorText.
Christian Aichinger
1
DAS WAR WUNDERBAR! Ich habe an Bildübergängen gearbeitet, und das CSS wird wirklich langsamer, wenn Sie ein großes Bild zum Schneiden in 36 separate URIs einfügen. Das hat mir nur eine Menge Aufwand gekostet. Vielen Dank!
Jason Maggard
1
Verwenden Sie dies im Jahr 2016: developer.mozilla.org/en-US/docs/Web/API/CSS_Object_Model/…
the_web
document.styleSheets[styleIndex].cssRules.[ruleIndex].style = {'color':'red', 'background-color':'green'};hat für mich gearbeitet, danke!
Pavel
43

Bitte! Fragen Sie einfach w3 ( http://www.quirksmode.org/dom/w3c_css.html )! Oder eigentlich habe ich fünf Stunden gebraucht ... aber hier ist es!

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
    }
}

Die Funktion ist sehr einfach zu bedienen. Beispiel:

<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>

Oh..


BEARBEITEN : Wie in der Antwort von @ user21820 beschrieben, ist es möglicherweise etwas unnötig, alle Stylesheets auf der Seite zu ändern. Das folgende Skript funktioniert sowohl mit IE5.5 als auch mit dem neuesten Google Chrome und fügt nur die oben beschriebene Funktion css () hinzu.

(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);
Leonard Pauli
quelle
Ernsthaft einfache Implementierung. Vielen Dank
Kaleb Anderson
1
Gibt es einen Grund, jedes einzelne Stylesheet zu ändern, anstatt nur ein einzelnes neu erstelltes wie in meiner Antwort?
user21820
Sehr schöne Umsetzung. Ein großes Lob an Sie, Sir.
Jason Maggard
1
@ user21820, wahrscheinlich nicht. Ich denke, ich wollte wirklich auf der sicheren Seite sein. Antwort endlich aktualisiert, ein großes Lob an Sie :)
Leonard Pauli
10

Ich habe den Code in den Antworten gesammelt und diese Funktion geschrieben, die auf meinem FF 25 gut zu laufen scheint.

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
}

Dies ist eine Möglichkeit, Werte in das CSS einzufügen, die in JS verwendet werden, auch wenn sie vom Browser nicht verstanden werden. zB maxHeight für einen Körper in einer gescrollten Tabelle.

Anruf :

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

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

FrViPofm
quelle
1
Wenn der Stil in die HTML-Seite eingebettet ist, document.styleSheets[m].hrefist er null und schlägt fehl.
JCM
4

Ich weiß nicht, warum die anderen Lösungen die gesamte Liste der Stylesheets für das Dokument durchgehen. Dadurch wird in jedem Stylesheet ein neuer Eintrag erstellt, der ineffizient ist. Stattdessen können wir einfach ein neues Stylesheet anhängen und dort einfach unsere gewünschten CSS-Regeln hinzufügen.

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){}
}

Beachten Sie, dass wir sogar Inline-Stile überschreiben können, die direkt für Elemente festgelegt wurden, indem wir dem Wert der Eigenschaft "! Important" hinzufügen, es sei denn, es gibt bereits spezifischere "! Important" -Stildeklarationen für diese Eigenschaft.

user21820
quelle
1
Eine kompliziertere Version finden Sie unter developer.mozilla.org/en-US/docs/Web/API/CSSStyleSheet/… .
user21820
1
Sehr richtig. Stellen Sie sicher, dass Sie .addRule (Selektor, Eigenschaft + ':' + Wert) verwenden, wenn .insertRule fehlschlägt (für die Unterstützung vor IE9).
Leonard Pauli
3

Ich habe nicht genug Repräsentanten, um Kommentare abzugeben, daher formatiere ich eine Antwort, aber es ist nur eine Demonstration des fraglichen Problems.

Wenn Elementstile in Stylesheets definiert werden, sind sie anscheinend für getElementById ("someElement") nicht sichtbar

Dieser Code veranschaulicht das Problem ... Code von unten auf jsFiddle .

In Test 2 ist beim ersten Aufruf der verbleibende Wert der Elemente undefiniert, und so wird das, was ein einfacher Umschalter sein sollte, durcheinander gebracht. Für meine Verwendung werde ich meine wichtigen Stilwerte inline definieren, aber es scheint den Zweck des Stylesheets teilweise zu verfehlen.

Hier ist der Seitencode ...

<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>

Ich hoffe, dies hilft, das Problem zu beleuchten.

Überspringen

BentFX
quelle
2

Sie können die "berechneten" Stile jedes Elements abrufen.

IE verwendet etwas namens "currentStyle", Firefox (und ich nehme an, dass andere "standardkonforme" Browser) "defaultView.getComputedStyle" verwendet.

Dazu müssen Sie eine browserübergreifende Funktion schreiben oder ein gutes Javascript-Framework wie Prototype oder jQuery verwenden (suchen Sie in der Javascript-Datei des Prototyps nach "getStyle" und in der Javerycript-Datei "curCss").

Das heißt, wenn Sie die Höhe oder Breite benötigen, sollten Sie wahrscheinlich element.offsetHeight und element.offsetWidth verwenden.

Der zurückgegebene Wert ist Null. Wenn ich also Javascript habe, das die Breite von etwas kennen muss, um eine Logik auszuführen (ich erhöhe die Breite um 1%, nicht auf einen bestimmten Wert).

Wenn Sie dem betreffenden Element einen Inline-Stil hinzufügen, kann dieser als "Standard" -Wert fungieren und kann beim Laden der Seite von Javascript gelesen werden, da es sich um die Inline-Stileigenschaft des Elements handelt:

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

quelle
0

Mit diesem einfachen 32-Zeilen-Inhalt können Sie ein bestimmtes Stylesheet identifizieren und seine Stile sehr einfach ändern:

var styleSheet = StyleChanger("my_custom_identifier");
styleSheet.change("darkolivegreen", "blue");
Solendil
quelle
0

Ich habe noch nie eine praktische Anwendung davon gesehen, aber Sie sollten wahrscheinlich DOM-Stylesheets in Betracht ziehen . Ich denke jedoch ehrlich, dass das übertrieben ist.

Wenn Sie einfach die Breite und Höhe eines Elements ermitteln möchten, unabhängig davon, von wo aus die Bemaßungen angewendet werden, verwenden Sie einfach element.offsetWidthund element.offsetHeight.

Rakesh Pai
quelle
Meine Verwendung: <style> #tid {width: 10%; } </ style> <div id = 'tid' onclick = "erhöhen ('tid')"> </ div> erhöhen prüft, ob die Breite <100% ist, wenn ja, erhöht sie sich um 1%. document.getElementById.style.width gibt null zurück, da kein Inline-Wert vorhanden ist. Gibt es einen einfacheren Weg als DOM Stylesheets?
Coltin
0

Vielleicht versuchen Sie Folgendes:

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
}
Shaq
quelle