web-dev-qa-db-fra.com

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

D'habitude, 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 de l'exécution d'actions à l'exécution, ou quelque chose de similaire? (uniquement en utilisant 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 DOM spécifiques.

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

178
stephan

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

257
Taras Bulba

Simplement

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

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

104
Shadrack B. Orina

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

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

Et ensuite, appliquez-le simplement à tous les éléments souhaités

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

Donc, c'est réutilisable. Dans quel but ferais-tu cela?

18
Yuval Karmi

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 de navigateur croisé.

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

Voici un plugin jquery qui vous permet d’injecter du CSS:

https://github.com/kajic/jquery-injectCSS

Exemple:

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

Ce n'est pas quelque chose de nouveau comparé à certaines des autres réponses car il utilise le concept décrit ici et ici , mais je voulais utiliser la 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 s'il 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. :)

9
sjngm

Si vous ne souhaitez pas coder en dur le code CSS dans un bloc/fichier CSS, vous pouvez utiliser jQuery pour ajouter de manière dynamique du code CSS à des éléments HTML, des identifiants et des 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);
});
7
Mike Trpcic

Notez que jQuery().css() ne modifie pas les règles de la feuille de style, il modifie 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 script <head> avant la création des éléments DOM et donc avant la première restitution du document, en évitant un rendu gênant visuellement, puis en effectuant un calcul, puis une restitution. Avec jQuery, vous devez attendre que les éléments DOM soient créés, puis les remodeler et les restituer.
  • Les éléments ajoutés dynamiquement après le restyle se verront automatiquement appliquer les nouveaux styles 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 un peu de modification pour que cela fonctionne bien sur les anciennes versions d'IE. En particulier, les anciennes versions de IE peuvent ne pas avoir défini s.cssRules, de sorte qu'elles retombent sur s.rules, qui présente certaines particularités, telles que le comportement impair/buggy lié à la délimitation par des virgules. sélecteurs, comme "body, p". Si vous les évitez, les versions IE précédentes ne seront peut-être pas modifiées, mais je ne l'ai pas encore testé.
  • Actuellement, les sélecteurs doivent correspondre exactement: utilisez des minuscules et faites attention aux listes délimitées par des virgules; l'ordre doit correspondre et être au format "first, second" c'est-à-dire que le délimiteur est une virgule suivie d'un caractère d'espacement.
  • On pourrait probablement y consacrer un peu plus de temps à essayer de détecter et de gérer intelligemment les sélecteurs se chevauchant, tels que ceux figurant dans des listes délimitées par des virgules.
  • On pourrait aussi ajouter un support pour les requêtes de média et le modificateur !important sans trop de peine.

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

5
Craig

L'ajout de règles personnalisées est utile si vous créez un widget jQuery nécessitant un code CSS personnalisé (tel que 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 balise HTML comporte un bouton avec un identifiant "addrule" et un div avec un identifiant de "cible" 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 cssrules 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 devez utiliser une variable locale persistante.

5
fbloggs

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

Je n'ai pas essayé cela, mais juste une théorie qui pourrait fonctionner.

3
Bryan Denny

Dans des cas (inhabituels) où vous voulez pouvoir changer souvent de style de façon dynamique - par exemple, une application de générateur de thème - l'ajout de balises <style> ou l'appel de CSSStyleSheet.insertRule () génère une feuille de style en croissance pouvant avoir des conséquences en termes de débogage des performances et de la conception.

Mon approche ne permet qu'une seule règle par combo sélecteur/propriété, en effaçant toutes les règles existantes. 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
Jason Boyd

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

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

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

2
Robert Gowland

Un peu paresseux répondre à cela, mais l'article suivant peut aider: http://www.javascriptkit.com/dhtmltutors/externalcss3.shtml

Aussi, essayez de taper "modifier les règles CSS" dans Google

Vous ne savez pas exactement ce qui se passerait si vous essayiez d'envelopper un document.styleSheets [0] avec jQuery () bien que vous puissiez l'essayer

2
James Wiseman

Voici une configuration qui commande 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);}
2
Chris Glasier

si vous ne voulez pas affecter d'affichage: aucun à une classe CSS, la bonne approche pour ajouter du style, jQuery.Rule fait le travail.

Dans certains cas, vous souhaitez appliquer des stiles avant l'événement append de contenu ajax et un fondu de contenu après append et le tour est joué!

1
Mattia

Vous pouvez utiliser cette bibliothèque appelée cssobj

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

Chaque fois que 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 lib qui fait ça.

1
James Yang

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
berniecc

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

La première façon dont je me suis aperçu lorsque je cherchais une orientation change pour que vous puissiez voir si le téléphone est en portrait ou en paysage, c’est une façon très statique mais simple et astucieuse:

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 votre fichier JS d'abord, puis dans une balise body):

<body onorientationchange="updateOrientation();">

Cela permet de choisir un autre bloc CSS prédéfini à exécuter en fonction du résultat renvoyé par le fichier JS.

De plus, le moyen le plus dynamique que j'ai préféré é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 vaut mieux enlever ses munitions avec quelque chose de plus étroit:

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 plage d'éléments.

J'espère que cela t'aides!

Cendre.

0
Ash