Erstellen Sie zur Laufzeit eine CSS-Regel / Klasse mit jQuery

188

Normalerweise habe ich eine CSS-Datei mit der folgenden Regel:

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

Wie kann ich vermeiden, eine solche statische CSS-Datei zu erstellen, indem ich die CSS-Informationen während der Laufzeitaktionen zum Body hinzufüge oder ähnliches? (nur mit jQuery)

Ich möchte es einmal definieren, aber mit jQuery und später viele Male verwenden. Deshalb möchte ich es nicht jedes Mal zu den spezifischen DOM-Elementen hinzufügen.

Ich kenne die einfachen Funktionen ( css("attr1", "value");), aber wie kann ich eine vollständige wiederverwendbare CSS-Regel erstellen?

stephan
quelle

Antworten:

268

Sie können ein Stilelement erstellen und in DOM einfügen

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

getestet auf Opera10 FF3.5 iE8 iE6

Taras Bulba
quelle
Das Wesentliche ist autark. Sie können es lokal erstellen, und es wird gut funktionieren. Direkter Link zum Download-Link: gist.github.com/gists/714352/download
Daniel Ribeiro
Kein Problem. Manchmal kann es sich um einen kleinen Versionsfehler von jQuery oder nur um ein falsches Setup handeln. Der Deal mit js Apps ist folgender: Wenn sie nicht funktionieren, funktionieren sie überhaupt nicht. Keine Vergebung.
Daniel Ribeiro
1
Wirft in IE8 den Fehler " Unerwarteter Aufruf des Methoden- oder Eigenschaftszugriffs " aus. Ich musste diesem Artikel folgen , damit er funktioniert.
Brandon Boone
6
Es können nur 31 Stile in der Seite in IE9-blogs.msdn.com/b/ieinternals/archive/2011/05/14/…
IvanH
1
Wenn es nicht funktioniert. Versuchen Sie, Stil an anzuhängen body. dh$("<style>...</style>").appendTo("body");
inDream
118

Einfach

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

Haben Sie die Schrägstriche bemerkt? Sie werden verwendet, um Zeichenfolgen zu verbinden, die sich in neuen Zeilen befinden. Wenn Sie sie weglassen, wird ein Fehler generiert.

Bogonko
quelle
6
Dies. Sollte die akzeptierte Antwort sein. Es beantwortet tatsächlich die Frage.
Johannes Pille
2
Ich stimme @JohannesPille zu, das ist die wahre Antwort!
Bayu
funktioniert nicht in cordova ios. Würden Sie dies bitte vorschlagen?
RamGrg
2
Sehr effizient und unkompliziert. Sobald die neue Regel in den Header eingefügt wurde, können Sie sie an einer beliebigen Stelle auf Ihrer Seite abrufen, auch in PHP.
Brice Coustillas
das gleiche wie stackoverflow.com/questions/1720320/…
user1742529
17

Sie können CSS auf ein Objekt anwenden. So können Sie Ihr Objekt in Ihrem Javascript folgendermaßen definieren:

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

Und wenden Sie es dann einfach auf alle gewünschten Elemente an

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

Es ist also wiederverwendbar. Zu welchem ​​Zweck würden Sie dies tun?

Yuval Karmi
quelle
22
Ich würde sagen, dies ist eine CSS-Regel und keine CSS-Klasse.
Hippietrail
17
Diese Antwort ist irreführend. Der Fragesteller wollte zur Laufzeit eine CSS-Regel erstellen und nicht den Stil eines bestimmten Elements auf eine konstante (wiederverwendbare) CSS-Deklaration festlegen.
Dan Dascalescu
4
Es ist nicht ganz das, wonach sie gefragt haben, aber es ist die richtige Lösung :) Das Füllen des Doms mit zusätzlichen <style> -Elementen hat einen üblen Code-Geruch
Kevin
3
Wie werden Sie diese Regeln entfernen, die angewendet werden, wenn Sie müssen, das ist mit anderen Lösungen möglich ...
Vishwanath
@ Kevin - das mag sein, aber es gibt Zeiten, in denen das genau das ist, was du brauchst. Beispiel: Wenn ein Element von einem Ajax-Skript neu erstellt wird und Sie eine neue Stilregel beibehalten müssen.
Billynoah
12

Sie können insertRule verwenden, wenn Sie laut dottoro IE <9 nicht unterstützen müssen . Dort drüben gibt es auch ein bisschen browserübergreifenden Code.

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

Hier ist ein JQuery-Plugin, mit dem Sie CSS injizieren können:

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

Beispiel:

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

Dies ist nichts Neues im Vergleich zu einigen anderen Antworten, da das hier und hier beschriebene Konzept verwendet wird , aber ich wollte die Deklaration im JSON-Stil verwenden:

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

Verwendung:

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

Ich bin nicht sicher, ob es alle Funktionen von CSS abdeckt, aber bisher funktioniert es für mich. Wenn dies nicht der Fall ist, betrachten Sie es als Ausgangspunkt für Ihre eigenen Bedürfnisse. :) :)

sjngm
quelle
7

Wenn Sie das CSS nicht fest in einen CSS-Block / eine CSS-Datei codieren möchten, können Sie mit jQuery HTML-Elementen, IDs und Klassen dynamisch CSS hinzufügen.

$(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);
});
Mike Trpcic
quelle
5
Diese Antwort ist nicht ganz das, wonach der Fragesteller gefragt hat. Der Fragesteller wollte zur Laufzeit eine CSS-Regel erstellen und nicht den Stil eines bestimmten Elements auf eine konstante CSS-Deklaration festlegen.
Dan Dascalescu
Ich verstehe, aber dies ist eine alternative Lösung, also habe ich sie bereitgestellt.
Mike Trpcic
2
@MikeTrpcic Das Problem ist, dass auch andere Leute nach dieser Lösung suchen - um einer Seite CSS-Regeln hinzuzufügen - und Ihre Antwort löst das nicht.
nate
5

Das Hinzufügen benutzerdefinierter Regeln ist nützlich, wenn Sie ein jQuery-Widget erstellen, für das benutzerdefiniertes CSS erforderlich ist (z. B. das vorhandene jQueryUI-CSS-Framework für Ihr bestimmtes Widget erweitern). Diese Lösung baut auf Taras 'Antwort auf (die erste oben).

Angenommen, Ihr HTML-Markup verfügt über eine Schaltfläche mit der ID "addrule" und ein div mit der ID "target", die Text enthält:

jQuery-Code:

$( "#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");     
}       

Der Vorteil dieses Ansatzes besteht darin, dass Sie variable cssrules in Ihrem Code wiederverwenden können, um Regeln nach Belieben hinzuzufügen oder zu entfernen. Wenn cssrules in ein persistentes Objekt wie ein jQuery-Widget eingebettet ist, können Sie mit einer persistenten lokalen Variablen arbeiten.

fbloggs
quelle
Was für eine schöne Idee! Ich habe es in Verbindung mit dem Snippet auf dieser Seite ssdtutorials.com/tutorials/title/jquery-flashing-text.html verwendet , um das Umschalten einer Farbe zu ermöglichen (das Original würde nur eine Klasse umschalten ). Vielen Dank!
bgmCoder
5

Beachten Sie, dass jQuery().css()die Stylesheet-Regeln nicht geändert werden, sondern nur der Stil jedes übereinstimmenden Elements.

Stattdessen habe ich hier eine Javascript-Funktion geschrieben, um die Stylesheet-Regeln selbst zu ändern.

    /**
     * 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);
        }
    }

Vorteile:

  • Stile können in einem <head>Skript berechnet werden, bevor die DOM-Elemente erstellt werden, und daher vor dem ersten Rendern des Dokuments, wobei ein visuell störendes Rendern vermieden, dann berechnet und dann erneut gerendert wird. Mit jQuery müssen Sie warten, bis die DOM-Elemente erstellt wurden, und sie dann neu formatieren und neu rendern.
  • Bei Elementen, die nach dem Neustil dynamisch hinzugefügt werden, werden die neuen Stile automatisch angewendet, ohne dass ein zusätzlicher Aufruf erforderlich ist jQuery(newElement).css()

Vorsichtsmaßnahmen:

  • Ich habe es auf Chrome und IE10 verwendet. Ich denke, es könnte eine kleine Modifikation erfordern, damit es auf älteren Versionen von IE gut funktioniert. Insbesondere ältere Versionen von IE wurden möglicherweise nicht s.cssRulesdefiniert, sodass sie auf s.ruleseinige Besonderheiten zurückgreifen , wie z. B. merkwürdiges / fehlerhaftes Verhalten in Bezug auf durch Kommas getrennte Selektoren, wie z"body, p" . Wenn Sie diese vermeiden, sind Sie in älteren IE-Versionen möglicherweise ohne Änderungen in Ordnung, aber ich habe es noch nicht getestet.
  • Derzeit müssen die Selektoren genau übereinstimmen: Verwenden Sie Kleinbuchstaben und gehen Sie vorsichtig mit durch Kommas getrennten Listen um. Die Reihenfolge muss übereinstimmen und sie sollten das Format haben, "first, second"dh das Trennzeichen ist ein Komma, gefolgt von einem Leerzeichen.
  • Man könnte wahrscheinlich etwas mehr Zeit damit verbringen, überlappende Selektoren zu erkennen und intelligent zu handhaben, beispielsweise in durch Kommas getrennten Listen.
  • Man könnte auch Unterstützung für Medienabfragen und den !importantModifikator ohne allzu große Probleme hinzufügen .

Wenn Sie diese Funktion verbessern möchten, finden Sie hier einige nützliche API-Dokumente: https://developer.mozilla.org/en-US/docs/Web/API/CSSStyleSheet

Craig
quelle
5

In (ungewöhnlichen) Fällen, in denen Sie Stile häufig dynamisch ändern möchten, z. B. in einer Theme Builder-App, führt das Hinzufügen von <style> -Tags oder das Aufrufen von CSSStyleSheet.insertRule () zu einem wachsenden Stylesheet, das Leistung und Design aufweisen kann Auswirkungen auf das Debuggen.

Mein Ansatz erlaubt nur eine einzige Regel pro Selektor / Eigenschaft-Kombination, wodurch alle beim Festlegen einer Regel vorhandenen Regeln gelöscht werden. Die API ist einfach und flexibel:

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

Verwendung:

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

clearStyle('body', 'background-color');
addStyle('body', 'color', '#333')
Jason Boyd
quelle
3

Was ist, wenn Sie dynamisch einen <Skript> -Abschnitt auf Ihrer Seite geschrieben haben (mit Ihren dynamischen Regeln) und dann jQuerys .addClass (Klasse) verwendet haben, um diese dynamisch erstellten Regeln hinzuzufügen?

Ich habe dies nicht versucht, sondern nur eine Theorie angeboten, die funktionieren könnte.

Bryan Denny
quelle
Nähte der beste Weg jetzt. Ich habe etwas gefunden jQuery.cssRule, aber es ist eine Art Plugin: - /
stephan
2
$ ("head"). append ($ ("<style type = 'text / css'> ... ist eine Möglichkeit
stephan
2

Eine etwas faule Antwort darauf, aber der folgende Artikel kann helfen: http://www.javascriptkit.com/dhtmltutors/externalcss3.shtml

Versuchen Sie auch, "CSS-Regeln ändern" in Google einzugeben

Ich bin mir nicht sicher, was passieren würde, wenn Sie versuchen würden, ein document.styleSheets [0] mit jQuery () zu verpacken, obwohl Sie es versuchen könnten

James Wiseman
quelle
2

Sie können das cssRule-Plug-In verwenden . Der Code war damals einfach:

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

In einem der bisherigen Kommentare wurde gefragt, warum man so etwas tun möchte. Erstellen Sie beispielsweise Stile für eine Liste, in der jedes Element eine bestimmte Hintergrundfarbe benötigt (z. B. die Kalenderliste von GCal), in der die Anzahl der Spalten erst zur Laufzeit bekannt ist.

Robert Gowland
quelle
@ Daniel, ja, das tut es; Anweisung entfernt.
Robert Gowland
scheint nicht Regel wie diese zu unterstützen:div:before{content:'name: ';}
Liuyanghejerry
2

Hier ist ein Setup, das den Befehl über Farben mit diesem JSON-Objekt gibt

 "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)"]
  }

diese Funktion

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

um dieses Stilelement zu produzieren

.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);}
Chris Glasier
quelle
1

Wenn Sie einer CSS-Klasse keine Anzeige zuweisen möchten: Keine, der richtige Ansatz zum Anhängen an den Stil, jQuery.Rule erledigt den Job.

In einigen Fällen möchten Sie Stile vor dem Anhängen von Ajax-Inhalten anwenden und Inhalte nach dem Anhängen verblassen, und das ist es!

Mattia
quelle
1

Hier haben Sie eine Funktion, um die vollständige Definition einer CSS-Klasse zu erhalten:

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 '';
};
berniecc
quelle
1

Sie können diese Bibliothek namens cssobj verwenden

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

Sie können Ihre Regeln jederzeit wie folgt aktualisieren:

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

Dann hast du die Regel geändert. jQuery ist nicht die Bibliothek, die dies tut.

James Yang
quelle
0

Ich habe in letzter Zeit mit einigen davon herumgespielt und beim Programmieren einer iPhone / iPod-Site zwei verschiedene Ansätze verwendet.

Der erste Weg, den ich bei der Suche nach Orientierungsänderungen gefunden habe, damit Sie sehen können, ob das Telefon im Hoch- oder Querformat ist, ist ein sehr statischer Weg, aber einfach und clever:

In CSS:

#content_right,
#content_normal{
 display:none;
}

In der JS-Datei:

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

In PHP / HTML (Importieren Sie zuerst Ihre JS-Datei und dann in das Body-Tag):

<body onorientationchange="updateOrientation();">

Dies wählt grundsätzlich einen anderen voreingestellten CSS-Block aus, der ausgeführt werden soll, abhängig vom Ergebnis, das aus der JS-Datei zurückgegeben wird.

Die dynamischere Art, die ich bevorzugte, war auch eine sehr einfache Ergänzung zu einem Skript-Tag oder Ihrer JS-Datei:

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

Dies funktioniert für die meisten Browser, aber für IE ist es am besten, die Munition mit etwas Festerem wegzunehmen:

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

Oder Sie können getElementByClass()eine Reihe von Elementen verwenden und ändern.

Hoffe das hilft!

Asche.

Asche
quelle
-2

Vielleicht können Sie die Stilinformationen in eine separate Klasse in Ihrer CSS-Datei einfügen, z.

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

und dann jQuery an dem Punkt Ihrer Wahl verwenden, um diesen Klassennamen zum Element hinzuzufügen?

JorenB
quelle
1
und Sie möchten die Informationen auch nicht in den Kopfbereich Ihrer Seite einfügen (zwischen Stil-Tags)?
JorenB
-2

Sie könnten einfach eine CSS-Klasse erstellen, die so etwas wie .fixed-object heißt und alle Ihre CSS enthält ...

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

Dann in jquery, wann immer Sie möchten, dass etwas diesen Stil hat, fügen Sie einfach diese Klasse hinzu ...

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

Das scheint der einfachste Weg zu sein, es sei denn, ich verstehe falsch, was Sie tun müssen.

Sir David von Lee
quelle
-9

Durch die Verwendung von .addClass () in jquery können wir Elementen auf der Seite dynamisch Stil hinzufügen. z.B. Wir haben Stil

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

Jetzt können wir im Bereitschaftszustand von jquery CSS wie .addClass (myStyle) hinzufügen.

Avinash
quelle