Créer une règle / classe CSS avec jQuery au moment de l'exécution


192

Habituellement, j'ai un fichier CSS qui a la règle suivante:

#my-window {
    position: fixed;
    z-index: 102;
    display:none;
    top:50%;
    left:50%;
}

Comment éviter de créer un tel fichier CSS statique en ajoutant les informations CSS lors des actions d'exécution au corps, ou quelque chose de similaire? (en utilisant uniquement jQuery)

Je veux le définir une fois mais avec jQuery et l'utiliser plusieurs fois plus tard; c'est pourquoi je ne veux pas l'ajouter à chaque fois aux éléments spécifiques du DOM.

Je connais les fonctionnalités simples ( css("attr1", "value");), mais comment puis-je créer une règle CSS réutilisable complète?

Réponses:


272

Vous pouvez créer un élément de style et l'insérer dans le DOM

$("<style type='text/css'> .redbold{ color:#f00; font-weight:bold;} </style>").appendTo("head");
$("<div/>").addClass("redbold").text("SOME NEW TEXT").appendTo("body");

testé sur Opera10 FF3.5 iE8 iE6


L'essentiel est autosuffisant. Vous pouvez le créer localement et cela fonctionnera très bien. Lien direct vers le lien de téléchargement: gist.github.com/gists/714352/download
Daniel Ribeiro

Aucun problème. Parfois, il peut s'agir d'un bogue de version mineure de jQuery ou simplement d'une configuration incorrecte. Le problème avec les applications js est le suivant: si elles ne fonctionnent pas, elles ne fonctionnent tout simplement pas. Pas de pardon.
Daniel Ribeiro

1
Lève une erreur « Appel inattendu à la méthode ou à l'accès à la propriété » pour moi dans IE8. J'ai dû suivre cet article pour le faire fonctionner.
Brandon Boone

6
Il ne peut y avoir que 31 styles dans la page dans IE9- blogs.msdn.com/b/ieinternals/archive/2011/05/14/…
IvanH

1
Si ça ne marche pas. Essayez d'ajouter un style à body. ie$("<style>...</style>").appendTo("body");
inDream

120

Simplement

$("<style>")
    .prop("type", "text/css")
    .html("\
    #my-window {\
        position: fixed;\
        z-index: 102;\
        display:none;\
        top:50%;\
        left:50%;\
    }")
    .appendTo("head");

Vous avez remarqué les barres obliques arrière? Ils sont utilisés pour joindre des chaînes qui sont sur de nouvelles lignes. Les laisser de côté génère une erreur.


6
Ce. Devrait être la réponse acceptée. Cela répond en fait à la question.
Johannes Pille

2
Je suis d'accord avec @JohannesPille, c'est la vraie réponse!
bayu

ne fonctionne pas dans cordova ios. voulez-vous s'il vous plaît suggérer à ce sujet?
RamGrg

2
Assez efficace et simple. Une fois la nouvelle règle injectée dans l'en-tête, vous pouvez la récupérer n'importe où dans votre page, y compris depuis PHP.
Brice Coustillas


17

vous pouvez appliquer css à un objet. Vous pouvez donc définir votre objet dans votre javascript comme ceci:

var my_css_class = { backgroundColor : 'blue', color : '#fff' };

Et puis appliquez-le simplement à tous les éléments que vous souhaitez

$("#myelement").css(my_css_class);

C'est donc réutilisable. Dans quel but feriez-vous cela?


22
Je dirais que c'est une règle CSS et non une classe CSS.
hippietrail

17
Cette réponse est trompeuse. Le demandeur voulait créer une règle CSS au moment de l'exécution, et non définir le style d'un élément particulier sur une déclaration CSS constante (réutilisable).
Dan Dascalescu

4
Ce n'est pas tout à fait ce qu'ils ont demandé, mais c'est la bonne solution :) Remplir le dom avec des éléments <style> supplémentaires a une odeur de code désagréable
Kevin

3
Comment allez-vous supprimer ces règles appliquées lorsque vous en avez besoin, c'est possible avec d'autres solutions ...
Vishwanath

@Kevin - c'est peut-être le cas, mais il y a des moments où c'est exactement ce dont vous avez besoin. par exemple - lorsqu'un élément est recréé par un script ajax et que vous devez conserver une nouvelle règle de style.
billynoah

12

Vous pouvez utiliser insertRule si vous n'avez pas besoin de prendre en charge IE <9, selon dottoro . Il y a aussi un peu de code cross browser là-bas.

document.styleSheets[0].insertRule('#my-window {\
    position: fixed;\
    z-index: 102;\
    display:none;\
    top:50%;\
    left:50%;\
}', 0)


9

Ce n'est pas quelque chose de nouveau par rapport à certaines des autres réponses car il utilise le concept décrit ici et ici , mais je voulais utiliser une déclaration de style JSON:

function addCssRule(rule, css) {
  css = JSON.stringify(css).replace(/"/g, "").replace(/,/g, ";");
  $("<style>").prop("type", "text/css").html(rule + css).appendTo("head");
}

Usage:

addCssRule(".friend a, .parent a", {
  color: "green",
  "font-size": "20px"
});

Je ne sais pas si cela couvre toutes les fonctionnalités de CSS, mais jusqu'à présent, cela fonctionne pour moi. Si ce n'est pas le cas, considérez-le comme un point de départ pour vos propres besoins. :)


Pour plus de clarté, je suggérerais de nommer les paramètres selectoret body. Le remplacement de la virgule posera des problèmes lors de la spécification des polices ou de l'utilisation de rgb (), etc., mais dans l'ensemble, cette idée est bonne.
Palec

7

Si vous ne voulez pas coder en dur le CSS dans un bloc / fichier CSS, vous pouvez utiliser jQuery pour ajouter dynamiquement du CSS aux éléments HTML, aux ID et aux classes.

$(document).ready(function() {
  //Build your CSS.
  var body_tag_css = {
    "background-color": "#ddd",
    "font-weight": "",
    "color": "#000"
  }
  //Apply your CSS to the body tag.  You can enter any tag here, as
  //well as ID's and Classes.
  $("body").css(body_tag_css);
});

5
Cette réponse n'est pas tout à fait ce que le demandeur a demandé. Le demandeur voulait créer une règle CSS au moment de l'exécution, et non définir le style d'un élément particulier sur une déclaration CSS constante.
Dan Dascalescu

Je comprends, mais c'est une solution alternative, alors je l'ai fournie.
Mike Trpcic

2
@MikeTrpcic Le problème est qu'il y a aussi d'autres personnes qui recherchent cette solution - pour ajouter des règles css à une page - et votre réponse ne résout pas cela.
nate le

6

Notez que jQuery().css()cela ne change pas les règles de la feuille de style, cela change simplement le style de chaque élément correspondant.

Au lieu de cela, voici une fonction javascript que j'ai écrite pour modifier les règles de la feuille de style elles-mêmes.

    /**
     * Modify an existing stylesheet.
     * - sheetId - the id of the <link> or <style> element that defines the stylesheet to be changed
     * - selector - the id/class/element part of the rule.  e.g. "div", ".sectionTitle", "#chapter2"
     * - property - the CSS attribute to be changed.  e.g. "border", "font-size"
     * - value - the new value for the CSS attribute.  e.g. "2px solid blue", "14px"
     */
    function changeCSS(sheetId, selector, property, value){
        var s = document.getElementById(sheetId).sheet;
        var rules = s.cssRules || s.rules;
        for(var i = rules.length - 1, found = false; i >= 0 && !found; i--){
            var r = rules[i];
            if(r.selectorText == selector){
                r.style.setProperty(property, value);
                found = true;
            }
        }
        if(!found){
            s.insertRule(selector + '{' + property + ':' + value + ';}', rules.length);
        }
    }

Avantages:

  • Les styles peuvent être calculés dans un <head>script avant la création des éléments DOM et donc avant le premier rendu du document, évitant ainsi un rendu visuellement ennuyeux, puis calculer, puis re-rendre. Avec jQuery, vous devez attendre que les éléments DOM soient créés, puis les re-styliser et les restituer.
  • Les éléments qui sont ajoutés dynamiquement après le restyle verront automatiquement les nouveaux styles appliqués sans appel supplémentaire à jQuery(newElement).css()

Mises en garde:

  • Je l'ai utilisé sur Chrome et IE10. Je pense qu'il faudra peut-être une petite modification pour que cela fonctionne bien sur les anciennes versions d'IE. En particulier, les anciennes versions d'IE peuvent ne pas avoir été s.cssRulesdéfinies, elles reviendront donc à s.rulesce qui présente certaines particularités, telles que le comportement étrange / bogué lié aux sélecteurs délimités par des virgules, comme "body, p". Si vous évitez ceux-ci, vous pourriez être d'accord avec les anciennes versions d'IE sans modification, mais je ne l'ai pas encore testé.
  • Actuellement, les sélecteurs doivent correspondre exactement: utilisez des minuscules et soyez prudent avec les listes séparées par des virgules; l'ordre doit correspondre et ils doivent être au format, "first, second"c'est-à-dire que le délimiteur est une virgule suivie d'un espace.
  • On pourrait probablement passer un peu plus de temps dessus à essayer de détecter et de gérer intelligemment les sélecteurs qui se chevauchent, tels que ceux des listes délimitées par des virgules.
  • On pourrait également ajouter la prise en charge des requêtes multimédias et du !importantmodificateur sans trop de problèmes.

Si vous souhaitez apporter des améliorations à cette fonction, vous trouverez ici des documents d'API utiles: https://developer.mozilla.org/en-US/docs/Web/API/CSSStyleSheet


5

L'ajout de règles personnalisées est utile si vous créez un widget jQuery qui nécessite un CSS personnalisé (comme l'extension du framework CSS jQueryUI existant pour votre widget particulier). Cette solution s'appuie sur la réponse de Taras (la première ci-dessus).

En supposant que votre balisage HTML comporte un bouton avec un identifiant "addrule" et un div avec un identifiant "target" contenant du texte:

Code jQuery:

$( "#addrule" ).click(function () { addcssrule($("#target")); });

function addcssrule(target) 
{ 
var cssrules =  $("<style type='text/css'> </style>").appendTo("head");

cssrules.append(".redbold{ color:#f00; font-weight:bold;}"); 
cssrules.append(".newfont {font-family: arial;}"); 
target.addClass("redbold newfont");     
}       

L'avantage de cette approche est que vous pouvez réutiliser des règles css variables dans votre code pour ajouter ou soustraire des règles à volonté. Si cssrules est incorporé dans un objet persistant tel qu'un widget jQuery, vous avez une variable locale persistante avec laquelle travailler.


Quelle belle idée! Je l'ai utilisé en conjonction avec l'extrait de code sur cette page ssdtutorials.com/tutorials/title/jquery-flashing-text.html pour permettre de basculer une couleur (l'original basculerait une classe uniquement). Merci!
bgmCoder

5

Dans les cas (inhabituels) où vous voulez pouvoir changer de style dynamiquement souvent - par exemple une application de création de thème - l'ajout de balises <style> ou l'appel de CSSStyleSheet.insertRule () entraînera une feuille de style croissante, qui peut avoir des performances et un design implications de débogage.

Mon approche n'autorise qu'une seule règle par combo sélecteur / propriété, effaçant tout élément existant lors de la définition d'une règle. L'API est simple et flexible:

function addStyle(selector, rulename, value) {
    var stylesheet = getAppStylesheet();
    var cssRules = stylesheet.cssRules || stylesheet.rules;
    var rule = stylesheet.insertRule(selector + ' { ' + rulename + ':' + value + ';}', cssRules.length);
}

function clearStyle(selector, rulename) {
    var stylesheet = getAppStylesheet();
    var cssRules = stylesheet.cssRules || stylesheet.rules;
    for (var i=0; i<cssRules.length; i++) {
        var rule = cssRules[i];
        if (rule.selectorText == selector && rule.style[0] == rulename) {
            stylesheet.deleteRule(i);
            break;
        }
    }       
}

function addStyles(selector, rules) {
    var stylesheet = getAppStylesheet();
    var cssRules = stylesheet.cssRules || stylesheet.rules;
    for (var prop in rules) {
        addStyle(selector, prop, rules[prop]);
    }
}

function getAppStylesheet() {
    var stylesheet = document.getElementById('my-styles');
    if (!stylesheet) {
        stylesheet = $('<style id="my-styles">').appendTo('head')[0];
    }
    stylesheet = stylesheet.sheet;
    return stylesheet;
}

Usage:

addStyles('body', {
    'background-color': 'black',
    color: 'green',
    margin: 'auto'
});

clearStyle('body', 'background-color');
addStyle('body', 'color', '#333')

3

Et si vous écriviez dynamiquement une section <script> sur votre page (avec vos règles dynamiques), puis utilisiez jQuerys .addClass (classe) pour ajouter ces règles créées dynamiquement?

Je n'ai pas essayé cela, je propose simplement une théorie qui pourrait fonctionner.


couture la meilleure façon en ce moment. J'ai trouvé quelque chose de jQuery.cssRule mais c'est une sorte de plugin: - /
stephan

2
$ ("head"). append ($ ("<style type = 'text / css'> ... is one way
stephan


2

Vous pouvez utiliser un plug-in cssRule . Le code était alors simple:

$.cssRule("#my-window {
    position: fixed;
    z-index: 102;
    display:none;
    top:50%;
    left:50%;
}");

Un des commentaires jusqu'à présent demandait pourquoi on voudrait faire une telle chose. Par exemple, créer des styles pour une liste où chaque élément a besoin d'une couleur d'arrière-plan distincte (par exemple, la liste de calendriers de GCal) où le nombre de colonnes n'est pas connu avant l'exécution.


@Daniel, oui c'est vrai; déclaration supprimée.
Robert Gowland

semble ne pas prendre en charge une règle comme celle-ci:div:before{content:'name: ';}
liuyanghejerry

2

Voici une configuration qui donne la commande sur les couleurs avec cet objet json

 "colors": {
    "Backlink": ["rgb(245,245,182)","rgb(160,82,45)"],
    "Blazer": ["rgb(240,240,240)"],
    "Body": ["rgb(192,192,192)"],
    "Tags": ["rgb(182,245,245)","rgb(0,0,0)"],
    "Crosslink": ["rgb(245,245,182)","rgb(160,82,45)"],
    "Key": ["rgb(182,245,182)","rgb(0,118,119)"],
    "Link": ["rgb(245,245,182)","rgb(160,82,45)"],
    "Link1": ["rgb(245,245,182)","rgb(160,82,45)"],
    "Link2": ["rgb(245,245,182)","rgb(160,82,45)"],
    "Manager": ["rgb(182,220,182)","rgb(0,118,119)"],
    "Monitor": ["rgb(255,230,225)","rgb(255,80,230)"],
    "Monitor1": ["rgb(255,230,225)","rgb(255,80,230)"],
    "Name": ["rgb(255,255,255)"],
    "Trail": ["rgb(240,240,240)"],
    "Option": ["rgb(240,240,240)","rgb(150,150,150)"]
  }

cette fonction

 function colors(fig){
    var html,k,v,entry,
    html = []
    $.each(fig.colors,function(k,v){
        entry  = "." + k ;
        entry += "{ background-color :"+ v[0]+";";
        if(v[1]) entry += " color :"+ v[1]+";";
        entry += "}"
        html.push(entry)
    });
    $("head").append($(document.createElement("style"))
        .html(html.join("\n"))
    )
}

pour produire cet élément de style

.Backlink{ background-color :rgb(245,245,182); color :rgb(160,82,45);}
.Blazer{ background-color :rgb(240,240,240);}
.Body{ background-color :rgb(192,192,192);}
.Tags{ background-color :rgb(182,245,245); color :rgb(0,0,0);}
.Crosslink{ background-color :rgb(245,245,182); color :rgb(160,82,45);}
.Key{ background-color :rgb(182,245,182); color :rgb(0,118,119);}
.Link{ background-color :rgb(245,245,182); color :rgb(160,82,45);}
.Link1{ background-color :rgb(245,245,182); color :rgb(160,82,45);}
.Link2{ background-color :rgb(245,245,182); color :rgb(160,82,45);}
.Manager{ background-color :rgb(182,220,182); color :rgb(0,118,119);}
.Monitor{ background-color :rgb(255,230,225); color :rgb(255,80,230);}
.Monitor1{ background-color :rgb(255,230,225); color :rgb(255,80,230);}
.Name{ background-color :rgb(255,255,255);}
.Trail{ background-color :rgb(240,240,240);}
.Option{ background-color :rgb(240,240,240); color :rgb(150,150,150);}

1

si vous ne voulez pas attribuer un affichage: aucun à une classe css, la bonne approche pour ajouter au style, jQuery.Rule fera le travail.

Dans certains cas, vous souhaitez appliquer des stiles avant l'événement d'ajout du contenu ajax et fondre le contenu après l'ajout et c'est tout!


1

Ici, vous avez une fonction pour obtenir la définition complète d'une classe CSS:

getCSSStyle = function (className) {
   for (var i = 0; i < document.styleSheets.length; i++) {
       var classes = document.styleSheets[i].rules || document.styleSheets[i].cssRules;
       for (var x = 0; x < classes.length; x++) {
           if (classes[x].selectorText  && - 1 != classes[x].selectorText.indexOf(className)) {
               return classes[x].cssText || classes[x].style.cssText;
           }
       }
   }
   return '';
};

1

Vous pouvez utiliser cette bibliothèque appelée cssobj

var result = cssobj({'#my-window': {
  position: 'fixed',
  zIndex: '102',
  display:'none',
  top:'50%',
  left:'50%'
}})

À tout moment, vous pouvez mettre à jour vos règles comme ceci:

result.obj['#my-window'].display = 'block'
result.update()

Ensuite, vous avez changé la règle. jQuery n'est pas la bibliothèque qui fait cela.


0

J'ai récemment joué avec certains de ces problèmes et j'ai utilisé deux approches différentes lors de la programmation d'un site iPhone / iPod.

La première façon dont je suis tombée sur la recherche de changements d'orientation afin que vous puissiez voir si le téléphone est en mode portrait ou paysage, c'est une manière très statique mais simple et intelligente:

En CSS:

#content_right,
#content_normal{
 display:none;
}

Dans le fichier JS:

function updateOrientation(){
  var contentType = "show_";
  switch(window.orientation){
   case 0:
   contentType += "normal";
   break;

   case -90:
   contentType += "right";
   break; document.getElementById("page_wrapper").setAttribute("class",contentType);
}

En PHP / HTML (importez d'abord votre fichier JS puis dans la balise body):

<body onorientationchange="updateOrientation();">

Cela choisit essentiellement un bloc CSS prédéfini différent à exécuter en fonction du résultat renvoyé par le fichier JS.

De plus, la manière la plus dynamique que j'ai préférée était un ajout très simple à une balise de script ou à votre fichier JS:

document.getelementbyid(id).style.backgroundColor = '#ffffff';

Cela fonctionne pour la plupart des navigateurs, mais pour IE, il est préférable de retirer ses munitions avec quelque chose de plus serré:

var yourID = document.getelementbyid(id); 
 if(yourID.currentstyle) { 
  yourID.style.backgroundColor = "#ffffff";      // for ie :@ 
 } else { 
  yourID.style.setProperty("background-color", "#ffffff");        // everything else :)
 }

Ou vous pouvez utiliser getElementByClass()et modifier une gamme d'articles.

J'espère que cela t'aides!

Cendre.


-2

Vous pouvez peut-être mettre les informations de style dans une classe distincte dans votre fichier css, par exemple:

.specificstyle {
    position: fixed;
    z-index: 102;
    display:none;
    top:50%;
    left:50%;
}

puis utilisez jQuery au moment de votre choix pour ajouter ce nom de classe à l'élément?


1
et vous ne voulez pas non plus mettre les informations dans la section head de votre page (entre les balises de style)?
JorenB

-2

Vous pouvez simplement créer une classe css appelée quelque chose comme .fixed-object qui contient tout votre css ...

.fixed-object{
    position: fixed;
    z-index: 102;
    display:none;
    top:50%;
    left:50%;
}

Ensuite, dans jquery, chaque fois que vous voulez que quelque chose ait ce style, ajoutez-y simplement cette classe ...

$(#my-window).addClass('fixed-object');

Cela semble être le moyen le plus simple de le faire, à moins que je ne comprenne mal ce que vous devez faire.


-9

En utilisant .addClass () dans jquery, nous pouvons ajouter dynamiquement du style aux éléments de la page. par exemple. nous avons du style

.myStyle
{
  width:500px;
  height:300px;
  background-color:red;
 }

Maintenant dans l'état prêt de jquery, nous pouvons ajouter des css comme .addClass (myStyle)

En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.