Changer les valeurs CSS avec Javascript

105

Il est facile de définir des valeurs CSS en ligne avec javascript. Si je veux changer la largeur et que j'ai html comme ceci:

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

Tout ce que j'ai à faire est:

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

Cela changera les valeurs de la feuille de style en ligne. Normalement, ce n'est pas un problème, car le style en ligne remplace la feuille de style. Exemple:

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

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

Utilisation de ce Javascript:

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

J'obtiens ce qui suit:

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

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

C'est un problème, car non seulement je ne veux pas changer les valeurs en ligne, si je recherche la largeur avant de la définir, quand j'ai:

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

La valeur retournée est Null, donc si j'ai Javascript qui a besoin de connaître la largeur de quelque chose pour faire de la logique (j'augmente la largeur de 1%, pas à une valeur spécifique), revenir Null quand j'attends la chaîne "50% "ne fonctionne pas vraiment.

Donc ma question: j'ai des valeurs dans un style CSS qui ne sont pas situées en ligne, comment puis-je obtenir ces valeurs? Comment puis-je modifier le style au lieu des valeurs en ligne, avec un identifiant?

Coltin
la source
pouvez-vous modifier votre message? il y a des phrases incomplètes au début, je ne sais pas ce que vous cherchiez ...
Jason S
Je suis encore un peu confus sur ce que vous demandez. Demandez-vous 1) de changer le CSS lui-même qui changera tous les éléments à la fois? ou 2) pour changer le CSS pour un seul élément à la fois?
Mike
Je suis également confus quant à la question réelle. Le style actuel d'un objet ne sera pas nécessairement le même que l'attribut «style» de la balise.
MattJ
Désolé, je vais le modifier pour être plus clair. Je ne veux pas définir de CSS en ligne. J'aimerais pouvoir augmenter / diminuer la largeur du style. Je vais éditer avec un exemple complet de ce que je recherche.
Coltin

Réponses:

90

Ok, on dirait que vous voulez changer le CSS global afin de changer efficacement tous les éléments d'un style péticulaire à la fois. J'ai récemment appris à le faire moi-même grâce à un tutoriel de Shawn Olson . Vous pouvez directement référencer son code ici .

Voici le résumé:

Vous pouvez récupérer les feuilles de style via document.styleSheets. Cela renverra en fait un tableau de toutes les feuilles de style de votre page, mais vous pouvez dire sur laquelle vous vous trouvez via la document.styleSheets[styleIndex].hrefpropriété. Une fois que vous avez trouvé la feuille de style que vous souhaitez modifier, vous devez obtenir le tableau de règles. C'est ce qu'on appelle «règles» dans IE et «cssRules» dans la plupart des autres navigateurs. La manière de savoir sur quelle CSSRule vous vous trouvez est par la selectorTextpropriété. Le code de travail ressemble à ceci:

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.

Faites-moi savoir comment cela fonctionne pour vous et veuillez commenter si vous voyez des erreurs.

Mike
la source
1
Changer le CSS de cette façon est beaucoup plus rapide si vous avez plus de 100 éléments. Disons, par exemple, changer toutes les cellules d'une certaine partie d'un tableau à la fois.
EdH
5
Je ne trouve pas rule.valuedans FF 20. Il y a rule.stylecependant, qui est réglable et se comporte comme element.style. Cf. https://developer.mozilla.org/en-US/docs/DOM/CSSStyleRule . Vérifier rule.type == rule.STYLE_RULEpeut également être une bonne idée avant d'accéder rule.selectorText.
Christian Aichinger
1
C'ÉTAIT GÉNIAL! Je travaillais sur des transitions d'images, et le CSS ralentit vraiment lorsque vous commencez à mettre une grande image dans 36 URI séparés pour le découpage. Cela a juste pris une tonne de frais généraux sur mon script. Merci!
Jason Maggard
document.styleSheets[styleIndex].cssRules.[ruleIndex].style = {'color':'red', 'background-color':'green'};travaillé pour moi, merci!
Pavel
43

S'il vous plaît! Demandez simplement w3 ( http://www.quirksmode.org/dom/w3c_css.html )! Ou en fait, cela m'a pris cinq heures ... mais la voici!

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 fonction est vraiment simple à utiliser. Exemple:

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


EDIT: comme @ user21820 l'a décrit dans sa réponse, il peut être un peu inutile de changer toutes les feuilles de style de la page. Le script suivant fonctionne avec IE5.5 ainsi que le dernier Google Chrome, et ajoute uniquement la fonction css () décrite ci-dessus.

(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
la source
Implémentation sérieusement simple. Merci
Kaleb Anderson
1
Y a-t-il une raison de modifier chaque feuille de style par opposition à une seule nouvellement créée comme dans ma réponse?
user21820
Très belle mise en œuvre. Félicitations à vous monsieur.
Jason Maggard
1
@ user21820, probablement pas. Je suppose que je voulais vraiment être du bon côté .. Réponse enfin mise à jour, bravo à vous :)
Leonard Pauli
10

En rassemblant le code dans les réponses, j'ai écrit cette fonction qui semble bien fonctionner sur mon 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
}

C'est un moyen de mettre des valeurs dans le css qui seront utilisées dans JS même si elles ne sont pas comprises par le navigateur. par exemple maxHeight pour un tbody dans un tableau déroulé.

Appel :

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

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

FrViPofm
la source
1
Si le style est incorporé dans la page HTML, alors document.styleSheets[m].hrefsera nul et échouera.
JCM
4

Je ne sais pas pourquoi les autres solutions passent par toute la liste des feuilles de style du document. Cela crée une nouvelle entrée dans chaque feuille de style, ce qui est inefficace. Au lieu de cela, nous pouvons simplement ajouter une nouvelle feuille de style et y ajouter simplement les règles CSS souhaitées.

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

Notez que nous pouvons remplacer même les styles en ligne définis directement sur les éléments en ajoutant "! Important" à la valeur de la propriété, sauf s'il existe déjà des déclarations de style "! Important" plus spécifiques pour cette propriété.

user21820
la source
1
Voir developer.mozilla.org/en-US/docs/Web/API/CSSStyleSheet/… pour une version plus compliquée.
user21820
1
Très vrai. Veillez à utiliser .addRule (sélecteur, propriété + ':' + valeur) si .insertRule échoue (pour la prise en charge antérieure à IE9).
Leonard Pauli
3

Je n'ai pas assez de représentants pour commenter, je vais donc formater une réponse, mais ce n'est qu'une démonstration du problème en question.

Il semble que lorsque les styles d'éléments sont définis dans des feuilles de style, ils ne sont pas visibles pour getElementById ("someElement"). Style

Ce code illustre le problème ... Code ci-dessous sur jsFiddle .

Dans le test 2, lors du premier appel, la valeur des éléments laissés n'est pas définie, et donc, ce qui devrait être une simple bascule est foiré. Pour mon utilisation, je définirai mes valeurs de style importantes en ligne, mais cela semble partiellement aller à l'encontre de l'objectif de la feuille de style.

Voici le code de la page ...

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

J'espère que cela aidera à éclairer la question.

Sauter

BentFX
la source
2

Vous pouvez obtenir les styles "calculés" de n'importe quel élément.

IE utilise quelque chose appelé "currentStyle", Firefox (et je suppose que d'autres navigateurs "conformes aux standards") utilise "defaultView.getComputedStyle".

Vous devrez écrire une fonction de navigateur croisé pour ce faire, ou utiliser un bon framework Javascript comme prototype ou jQuery (recherchez "getStyle" dans le fichier javascript prototype et "curCss" dans le fichier javascript jquery).

Cela dit, si vous avez besoin de la hauteur ou de la largeur, vous devriez probablement utiliser element.offsetHeight et element.offsetWidth.

La valeur retournée est Null, donc si j'ai Javascript qui a besoin de connaître la largeur de quelque chose pour faire de la logique (j'augmente la largeur de 1%, pas à une valeur spécifique)

Attention, si vous ajoutez un style en ligne à l'élément en question, il peut agir comme valeur "par défaut" et sera lisible par Javascript au chargement de la page, car il s'agit de la propriété de style en ligne de l'élément:

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

la source
0

Ce simple résumé de 32 lignes vous permet d'identifier une feuille de style donnée et de modifier ses styles très facilement:

var styleSheet = StyleChanger("my_custom_identifier");
styleSheet.change("darkolivegreen", "blue");
solendil
la source
0

Je n'ai jamais vu d'utilisation pratique de cela, mais vous devriez probablement considérer les feuilles de style DOM . Cependant, je pense honnêtement que c'est exagéré.

Si vous souhaitez simplement obtenir la largeur et la hauteur d'un élément, quel que soit l'endroit à partir duquel les dimensions sont appliquées, utilisez simplement element.offsetWidthet element.offsetHeight.

Rakesh Pai
la source
Mon utilisation: <style> #tid {width: 10%; } </style> <div id = 'tid' onclick = "augmenter ('tid')"> </div> augmentera si la largeur est <100%, si c'est le cas, elle augmentera de 1%. document.getElementById.style.width renvoie null car il n'y a pas de valeur en ligne. Existe-t-il un moyen plus simple que les feuilles de style DOM?
Coltin
0

Essayez peut-être ceci:

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