Modifica dei valori CSS con Javascript


105

È facile impostare valori CSS in linea con javascript. Se voglio cambiare la larghezza e ho html come questo:

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

Tutto quello che devo fare è:

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

Cambierà i valori del foglio di stile in linea. Normalmente questo non è un problema, perché lo stile inline sovrascrive il foglio di stile. Esempio:

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

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

Utilizzando questo Javascript:

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

Ottengo quanto segue:

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

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

Questo è un problema, perché non solo non voglio cambiare i valori inline, se cerco la larghezza prima di impostarla, quando ho:

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

Il valore restituito è Null, quindi se ho Javascript che ha bisogno di conoscere la larghezza di qualcosa per fare un po 'di logica (aumento la larghezza dell'1%, non a un valore specifico), ritorno Null quando mi aspetto la stringa "50% "non funziona davvero.

Quindi la mia domanda: ho valori in uno stile CSS che non si trovano in linea, come posso ottenere questi valori? Come posso modificare lo stile invece dei valori inline, dato un id?


potresti modificare il tuo post? ci sono alcune frasi incomplete all'inizio, non sono sicuro di cosa stavi cercando ...
Jason S

Sono ancora un po 'confuso su quello che stai chiedendo. Stai chiedendo 1) di cambiare il CSS stesso che cambierà tutti gli elementi contemporaneamente? o 2) cambiare il CSS per un singolo elemento alla volta?
Mike

Sono anche confuso riguardo alla domanda vera e propria. Lo stile corrente di un oggetto non sarà necessariamente lo stesso dell'attributo 'style' del tag.
MattJ

Scusa se lo modifico per essere più chiaro. Non voglio impostare CSS in linea. Mi piacerebbe poter aumentare / diminuire la larghezza dello stile. Modificherò con un esempio completo di ciò che sto cercando.
Coltin

Risposte:


90

Ok, sembra che tu voglia cambiare il CSS globale in modo che cambierà efficacemente tutti gli elementi di uno stile particolare contemporaneamente. Recentemente ho imparato come farlo da solo da un tutorial di Shawn Olson . Puoi fare riferimento direttamente al suo codice qui .

Ecco il riassunto:

Puoi recuperare i fogli di stile tramite document.styleSheets. Questo restituirà effettivamente un array di tutti i fogli di stile nella tua pagina, ma puoi dire su quale ti trovi tramite la document.styleSheets[styleIndex].hrefproprietà. Una volta trovato il foglio di stile che desideri modificare, devi ottenere la matrice di regole. Questo è chiamato "regole" in IE e "cssRules" nella maggior parte degli altri browser. Il modo per sapere su quale CSSRule ti trovi è tramite la selectorTextproprietà. Il codice funzionante ha un aspetto simile a questo:

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.

Fammi sapere come funziona per te e per favore commenta se vedi errori.


1
Cambiare CSS in questo modo è molto più veloce se hai più di 100 elementi. Supponiamo, ad esempio, di cambiare tutte le celle in una certa parte di una tabella contemporaneamente.
EdH

5
Non riesco a trovare rule.valuein FF 20. C'è rule.styleperò, che è impostabile e si comporta come element.style. Cf. https://developer.mozilla.org/en-US/docs/DOM/CSSStyleRule . Controllare rule.type == rule.STYLE_RULEpotrebbe anche essere una buona idea prima di accedere rule.selectorText.
Christian Aichinger

1
È STATO FANTASTICO! Stavo lavorando sulle transizioni delle immagini e il CSS rallenta davvero quando inizi a inserire un'immagine grande in 36 URI separati per il taglio. Questo ha solo tolto un sacco di spese generali dal mio script. Grazie!
Jason Maggard


document.styleSheets[styleIndex].cssRules.[ruleIndex].style = {'color':'red', 'background-color':'green'};ha funzionato per me, grazie!
Pavel

43

Per favore! Basta chiedere a w3 ( http://www.quirksmode.org/dom/w3c_css.html )! O effettivamente, mi ci sono volute cinque ore ... ma eccolo!

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

La funzione è davvero facile da usare .. esempio:

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


MODIFICA: come @ user21820 descritto nella sua risposta, potrebbe essere un po 'inutile cambiare tutti i fogli di stile sulla pagina. Il seguente script funziona con IE5.5 così come con l'ultimo Google Chrome e aggiunge solo la funzione css () sopra descritta.

(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);

Implementazione seriamente facile. Grazie
Kaleb Anderson

1
C'è un motivo per modificare ogni singolo foglio di stile invece di uno solo appena creato come nella mia risposta?
user21820

Realizzazione molto bella. Complimenti a lei signore.
Jason Maggard

1
@ user21820, probabilmente no. Immagino che volevo davvero stare sul sicuro .. Risposta finalmente aggiornata, complimenti a te :)
Leonard Pauli

10

Raccogliendo il codice nelle risposte, ho scritto questa funzione che sembra funzionare bene sul mio 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
}

Questo è un modo per inserire valori nel css che verranno utilizzati in JS anche se non compresi dal browser. es. maxHeight per un tbody in una tabella a scorrimento.

Chiamata:

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

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


1
Se lo stile è incorporato nella pagina HTML, document.styleSheets[m].hrefsarà nullo e fallirà.
JCM

4

Non so perché le altre soluzioni passano attraverso l'intero elenco di fogli di stile per il documento. In questo modo viene creata una nuova voce in ogni foglio di stile, che è inefficiente. Invece, possiamo semplicemente aggiungere un nuovo foglio di stile e aggiungere semplicemente le nostre regole CSS desiderate lì.

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

Nota che possiamo sovrascrivere anche gli stili inline impostati direttamente sugli elementi aggiungendo "! Important" al valore della proprietà, a meno che non esistano già dichiarazioni di stile "! Important" più specifiche per quella proprietà.


1

1
Verissimo. Assicurati di utilizzare .addRule (selettore, proprietà + ':' + valore) se .insertRule fallisce (per il supporto precedente a IE9).
Leonard Pauli

3

Non ho abbastanza rappresentanti per commentare, quindi formatterò una risposta, ma è solo una dimostrazione del problema in questione.

Sembra che quando gli stili degli elementi sono definiti nei fogli di stile non sono visibili a getElementById ("someElement").

Questo codice illustra il problema ... Codice dal basso su jsFiddle .

Nel Test 2, alla prima chiamata, il valore degli elementi rimasti non è definito, quindi quello che dovrebbe essere un semplice interruttore viene incasinato. Per mio uso definirò i miei importanti valori di stile in linea, ma sembra in parte vanificare lo scopo del foglio di stile.

Ecco il codice della pagina ...

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

Spero che questo aiuti a chiarire la questione.

Salta


2

Puoi ottenere gli stili "calcolati" di qualsiasi elemento.

IE utilizza qualcosa chiamato "currentStyle", Firefox (e presumo altri browser "conformi agli standard") utilizza "defaultView.getComputedStyle".

Dovrai scrivere una funzione cross browser per fare questo, o usare un buon framework Javascript come prototype o jQuery (cerca "getStyle" nel file javascript prototipo e "curCss" nel file jquery javascript).

Detto questo, se hai bisogno dell'altezza o della larghezza dovresti probabilmente usare element.offsetHeight e element.offsetWidth.

Il valore restituito è Null, quindi se ho Javascript che ha bisogno di conoscere la larghezza di qualcosa per fare un po 'di logica (aumento la larghezza dell'1%, non a un valore specifico)

Tieni presente che se aggiungi uno stile inline all'elemento in questione, può agire come valore "predefinito" e sarà leggibile da Javascript al caricamento della pagina, poiché è la proprietà dello stile inline dell'elemento:

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

0

Questa semplice sintesi di 32 righe ti consente di identificare un dato foglio di stile e modificarne lo stile molto facilmente:

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

0

Non ho mai visto alcun uso pratico di questo, ma probabilmente dovresti considerare i fogli di stile DOM . Tuttavia, onestamente penso che sia eccessivo.

Se vuoi semplicemente ottenere la larghezza e l'altezza di un elemento, indipendentemente da dove vengono applicate le dimensioni, usa element.offsetWidthe element.offsetHeight.


Il mio utilizzo: <style> #tid {width: 10%; } </style> <div id = 'tid' onclick = "aumentare ('tid')"> </div> aumentare controllerà se la larghezza è <100%, in tal caso aumenterà dell'1%. document.getElementById.style.width restituisce null perché non è presente alcun valore inline. Esiste un modo più semplice dei fogli di stile DOM?
Coltin

0

Forse prova questo:

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
}
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.