it-swarm.com.de

Wie kann man CSS-Klassen dynamisch in JavaScript erstellen und anwenden?

Ich muss eine CSS-Stylesheet-Klasse dynamisch in JavaScript erstellen und sie einigen HTML-Elementen wie div, table, span, tr usw. und einigen Steuerelementen wie asp: Textbox, Dropdownlist und datalist zuweisen.

Ist es möglich?

Es wäre schön mit einer Probe.

252
Himadri

Obwohl ich nicht sicher bin, warum Sie CSS-Klassen mit JavaScript erstellen möchten, haben wir hier eine Option:

var style = document.createElement('style');
style.type = 'text/css';
style.innerHTML = '.cssClass { color: #F00; }';
document.getElementsByTagName('head')[0].appendChild(style);

document.getElementById('someElementId').className = 'cssClass';
343
I.devries

Eine bessere Lösung gefunden, die funktioniert mit allen Browsern.
Verwendet document.styleSheet, um Regeln hinzuzufügen oder zu ersetzen. Die akzeptierte Antwort ist kurz und praktisch, aber dies funktioniert in IE8 und auch weniger. 

function createCSSSelector (selector, style) {
  if (!document.styleSheets) return;
  if (document.getElementsByTagName('head').length == 0) return;

  var styleSheet,mediaType;

  if (document.styleSheets.length > 0) {
    for (var i = 0, l = document.styleSheets.length; i < l; i++) {
      if (document.styleSheets[i].disabled) 
        continue;
      var media = document.styleSheets[i].media;
      mediaType = typeof media;

      if (mediaType === 'string') {
        if (media === '' || (media.indexOf('screen') !== -1)) {
          styleSheet = document.styleSheets[i];
        }
      }
      else if (mediaType=='object') {
        if (media.mediaText === '' || (media.mediaText.indexOf('screen') !== -1)) {
          styleSheet = document.styleSheets[i];
        }
      }

      if (typeof styleSheet !== 'undefined') 
        break;
    }
  }

  if (typeof styleSheet === 'undefined') {
    var styleSheetElement = document.createElement('style');
    styleSheetElement.type = 'text/css';
    document.getElementsByTagName('head')[0].appendChild(styleSheetElement);

    for (i = 0; i < document.styleSheets.length; i++) {
      if (document.styleSheets[i].disabled) {
        continue;
      }
      styleSheet = document.styleSheets[i];
    }

    mediaType = typeof styleSheet.media;
  }

  if (mediaType === 'string') {
    for (var i = 0, l = styleSheet.rules.length; i < l; i++) {
      if(styleSheet.rules[i].selectorText && styleSheet.rules[i].selectorText.toLowerCase()==selector.toLowerCase()) {
        styleSheet.rules[i].style.cssText = style;
        return;
      }
    }
    styleSheet.addRule(selector,style);
  }
  else if (mediaType === 'object') {
    var styleSheetLength = (styleSheet.cssRules) ? styleSheet.cssRules.length : 0;
    for (var i = 0; i < styleSheetLength; i++) {
      if (styleSheet.cssRules[i].selectorText && styleSheet.cssRules[i].selectorText.toLowerCase() == selector.toLowerCase()) {
        styleSheet.cssRules[i].style.cssText = style;
        return;
      }
    }
    styleSheet.insertRule(selector + '{' + style + '}', styleSheetLength);
  }
}

Funktion wird wie folgt verwendet. 

createCSSSelector('.mycssclass', 'display:none');

Obwohl der Funktionsname createClass ist, wird tatsächlich ein Selektor erstellt. Vergessen Sie also nicht, vor dem Klassennamen. (Punkt) hinzuzufügen. Sie müssen nicht erwähnen, dass Sie mit dieser Funktion auch andere Selektoren erstellen können. 

104
Vishwanath

Kurze Antwort, dies ist "auf allen Browsern" (insbesondere IE8/7) kompatibel:

function createClass(name,rules){
    var style = document.createElement('style');
    style.type = 'text/css';
    document.getElementsByTagName('head')[0].appendChild(style);
    if(!(style.sheet||{}).insertRule) 
        (style.styleSheet || style.sheet).addRule(name, rules);
    else
        style.sheet.insertRule(name+"{"+rules+"}",0);
}
createClass('.whatever',"background-color: green;");

Und dieses letzte Bit wendet die Klasse auf ein Element an:

function applyClass(name,element,doRemove){
    if(typeof element.valueOf() == "string"){
        element = document.getElementById(element);
    }
    if(!element) return;
    if(doRemove){
        element.className = element.className.replace(new RegExp("\\b" + name + "\\b","g"));
    }else{      
        element.className = element.className + " " + name;
    }
}

Hier ist auch eine kleine Testseite: https://Gist.github.com/shadybones/9816763

Der Schlüssel ist die Tatsache, dass Stilelemente eine "styleSheet"/"sheet" -Eigenschaft haben, mit der Sie Regeln hinzufügen oder entfernen können.

24
shadybones

Es gibt ein leichtes jQuery-Plugin, mit dem CSS-Deklarationen generiert werden können: jQuery-injectCSS

Tatsächlich verwendet es JSS (von JSON beschriebenes CSS), aber es ist ziemlich einfach zu handhaben, um dynamische CSS-Stylesheets zu erzeugen.

$.injectCSS({
    "#test": {
        height: 123
    }
});
14
Yako

YUI hat mit Abstand das beste Stylesheet-Dienstprogramm , das ich da draußen gesehen habe. Ich möchte Sie dazu ermutigen, es auszuprobieren, aber hier ist ein Vorgeschmack:

// style element or locally sourced link element
var sheet = YAHOO.util.StyleSheet(YAHOO.util.Selector.query('style',null,true));

sheet = YAHOO.util.StyleSheet(YAHOO.util.Dom.get('local'));


// OR the id of a style element or locally sourced link element
sheet = YAHOO.util.StyleSheet('local');


// OR string of css text
var css = ".moduleX .alert { background: #fcc; font-weight: bold; } " +
          ".moduleX .warn  { background: #eec; } " +
          ".hide_messages .moduleX .alert, " +
          ".hide_messages .moduleX .warn { display: none; }";

sheet = new YAHOO.util.StyleSheet(css);

Es gibt offensichtlich andere, viel einfachere Möglichkeiten, den Stil im laufenden Betrieb zu ändern, wie hier vorgeschlagen. Wenn sie für Ihr Problem sinnvoll sind, sind sie vielleicht am besten, aber es gibt definitiv Gründe, warum das Ändern von CSS eine bessere Lösung ist. Der offensichtlichste Fall ist, wenn Sie eine große Anzahl von Elementen ändern müssen. Der andere wichtige Fall ist, wenn Sie Ihre Stiländerungen für die Kaskade benötigen. Die Verwendung des Dom zum Ändern eines Elements hat immer eine höhere Priorität. Dies ist der Vorschlaghammer-Ansatz und entspricht der Verwendung des style-Attributs direkt für das html-Element. Das ist nicht immer der gewünschte Effekt.

7
Russell Leggett

Ab IE 9. Sie können jetzt eine Textdatei laden und eine style.innerHTML -Eigenschaft festlegen. Im Wesentlichen können Sie nun eine CSS-Datei über ajax laden (und den Rückruf abrufen) und dann den Text innerhalb eines Style-Tags wie folgt festlegen.

Dies funktioniert in anderen Browsern, nicht sicher wie weit zurück. Aber solange Sie nicht IE8 unterstützen müssen, würde es funktionieren.

// RESULT: doesn't work in IE8 and below. Works in IE9 and other browsers.
$(document).ready(function() {
    // we want to load the css as a text file and append it with a style.
    $.ajax({
        url:'myCss.css',
        success: function(result) {
            var s = document.createElement('style');
            s.setAttribute('type', 'text/css');
            s.innerHTML = result;
            document.getElementsByTagName("head")[0].appendChild(s);
        },
        fail: function() {
            alert('fail');
        }
    })
});

und dann können Sie es eine externe Datei wie die myCss.css ziehen lassen

.myClass { background:#F00; }
5
Codeguy

https://jsfiddle.net/xk6Ut/256/

Eine Option zum dynamischen Erstellen und Aktualisieren der CSS-Klasse in JavaScript:

  • Verwenden von Style Element zum Erstellen eines CSS-Abschnitts 
  • Verwenden Sie eine ID für das Stilelement, damit wir das CSS aktualisieren können
    Klasse

.....

function writeStyles(styleName, cssText) {
    var styleElement = document.getElementById(styleName);
    if (styleElement) 
             document.getElementsByTagName('head')[0].removeChild(
        styleElement);
    styleElement = document.createElement('style');
    styleElement.type = 'text/css';
    styleElement.id = styleName;
    styleElement.innerHTML = cssText;
    document.getElementsByTagName('head')[0].appendChild(styleElement);
}

... 

    var cssText = '.testDIV{ height:' + height + 'px !important; }';
    writeStyles('styles_js', cssText)
3
Razan Paul

Hier ist die Lösung von Vishwanath, die leicht mit Kommentaren umgeschrieben wurde:

function setStyle(cssRules, aSelector, aStyle){
    for(var i = 0; i < cssRules.length; i++) {
        if(cssRules[i].selectorText && cssRules[i].selectorText.toLowerCase() == aSelector.toLowerCase()) {
            cssRules[i].style.cssText = aStyle;
            return true;
        }
    }
    return false;
}

function createCSSSelector(selector, style) {
    var doc = document;
    var allSS = doc.styleSheets;
    if(!allSS) return;

    var headElts = doc.getElementsByTagName("head");
    if(!headElts.length) return;

    var styleSheet, media, iSS = allSS.length; // scope is global in a function
    /* 1. search for media == "screen" */
    while(iSS){ --iSS;
        if(allSS[iSS].disabled) continue; /* dont take into account the disabled stylesheets */
        media = allSS[iSS].media;
        if(typeof media == "object")
            media = media.mediaText;
        if(media == "" || media=='all' || media.indexOf("screen") != -1){
            styleSheet = allSS[iSS];
            iSS = -1;   // indication that media=="screen" was found (if not, then iSS==0)
            break;
        }
    }

    /* 2. if not found, create one */
    if(iSS != -1) {
        var styleSheetElement = doc.createElement("style");
        styleSheetElement.type = "text/css";
        headElts[0].appendChild(styleSheetElement);
        styleSheet = doc.styleSheets[allSS.length]; /* take the new stylesheet to add the selector and the style */
    }

    /* 3. add the selector and style */
    switch (typeof styleSheet.media) {
    case "string":
        if(!setStyle(styleSheet.rules, selector, style));
            styleSheet.addRule(selector, style);
        break;
    case "object":
        if(!setStyle(styleSheet.cssRules, selector, style));
            styleSheet.insertRule(selector + "{" + style + "}", styleSheet.cssRules.length);
        break;
    }
3
user3705905

Ein interessantes Projekt, das Ihnen bei Ihrer Aufgabe helfen könnte, ist JSS .

JSS ist eine bessere Abstraktion als CSS. Es verwendet JavaScript als Sprache Stile deklarativ und wartbar zu beschreiben. Es ist ein hoher Performance JS to CSS Compiler, der zur Laufzeit in den Browsern und serverseitig arbeitet.

Mit der JSS-Bibliothek können Sie mit der Funktion .attach() in den DOM/head-Bereich injizieren.

Repl Online Version zur Auswertung.

Weitere Informationen zu JSS .

Ein Beispiel:

// Use plugins.
jss.use(camelCase())

// Create your style.
const style = {
  myButton: {
    color: 'green'
  }
}

// Compile styles, apply plugins.
const sheet = jss.createStyleSheet(style)

// If you want to render on the client, insert it into DOM.
sheet.attach()
2
GibboK
function createCSSClass(selector, style, hoverstyle) 
{
    if (!document.styleSheets) 
    {
        return;
    }

    if (document.getElementsByTagName("head").length == 0) 
    {

        return;
    }
    var stylesheet;
    var mediaType;
    if (document.styleSheets.length > 0) 
    {
        for (i = 0; i < document.styleSheets.length; i++) 
        {
            if (document.styleSheets[i].disabled) 
            {
                continue;
            }
            var media = document.styleSheets[i].media;
            mediaType = typeof media;

            if (mediaType == "string") 
            {
                if (media == "" || (media.indexOf("screen") != -1)) 
                {
                    styleSheet = document.styleSheets[i];
                }
            } 
            else if (mediaType == "object") 
            {
                if (media.mediaText == "" || (media.mediaText.indexOf("screen") != -1)) 
                {
                    styleSheet = document.styleSheets[i];
                }
            }

            if (typeof styleSheet != "undefined") 
            {
                break;
            }
        }
    }

    if (typeof styleSheet == "undefined") {
        var styleSheetElement = document.createElement("style");
        styleSheetElement.type = "text/css";
        document.getElementsByTagName("head")[0].appendChild(styleSheetElement);
        for (i = 0; i < document.styleSheets.length; i++) {
            if (document.styleSheets[i].disabled) {
                continue;
            }
            styleSheet = document.styleSheets[i];
        }

        var media = styleSheet.media;
        mediaType = typeof media;
    }

    if (mediaType == "string") {
        for (i = 0; i < styleSheet.rules.length; i++) 
        {
            if (styleSheet.rules[i].selectorText.toLowerCase() == selector.toLowerCase()) 
            {
                styleSheet.rules[i].style.cssText = style;
                return;
            }
        }

        styleSheet.addRule(selector, style);
    }
    else if (mediaType == "object") 
    {
        for (i = 0; i < styleSheet.cssRules.length; i++) 
        {
            if (styleSheet.cssRules[i].selectorText.toLowerCase() == selector.toLowerCase()) 
            {
                styleSheet.cssRules[i].style.cssText = style;
                return;
            }
        }

        if (hoverstyle != null) 
        {
            styleSheet.insertRule(selector + "{" + style + "}", 0);
            styleSheet.insertRule(selector + ":hover{" + hoverstyle + "}", 1);
        }
        else 
        {
            styleSheet.insertRule(selector + "{" + style + "}", 0);
        }
    }
}





createCSSClass(".modalPopup  .header",
                                 " background-color: " + lightest + ";" +
                                  "height: 10%;" +
                                  "color: White;" +
                                  "line-height: 30px;" +
                                  "text-align: center;" +
                                  " width: 100%;" +
                                  "font-weight: bold; ", null);
1
tushar

Google-Schließung verwenden:

sie können einfach das ccsom-Modul verwenden:

goog.require('goog.cssom');
var css_node = goog.cssom.addCssText('.cssClass { color: #F00; }');

Der Javascript-Code versucht, Browserübergreifend zu sein, wenn der CSS-Knoten in den Dokumentkopf eingefügt wird.

1
Joe Heyming

Sie haben die Antworten durchgesehen und das Offensichtlichste und Unkomplizierteste fehlt: Verwenden Sie document.write(), um einen Teil des benötigten CSS zu schreiben.

Hier ist ein Beispiel (siehe Codepen: http://codepen.io/ssh33/pen/zGjWga ): 

<style>
   @import url(http://fonts.googleapis.com/css?family=Open+Sans:800);
   .d, body{ font: 3vw 'Open Sans'; padding-top: 1em; }
   .d {
       text-align: center; background: #aaf;
       margin: auto; color: #fff; overflow: hidden; 
       width: 12em; height: 5em;
   }
</style>

<script>
   function w(s){document.write(s)}
   w("<style>.long-shadow { text-shadow: ");
   for(var i=0; i<449; i++) {
      if(i!= 0) w(","); w(i+"px "+i+"px #444");
   }
   w(";}</style>");
</script> 

<div class="d">
    <div class="long-shadow">Long Shadow<br> Short Code</div>
</div>
1
Stack

Ich habe einige der Antworten hier durchgesehen und konnte nichts finden, das automatisch ein neues Stylesheet hinzufügt, wenn es keines gibt, und falls nicht, ändert es einfach ein vorhandenes, das bereits den benötigten Stil enthält. sollte auf allen Browsern funktionieren, obwohl nicht getestet, verwendet addRule und abgesehen davon, dass nur grundlegendes natives JavaScript vorhanden ist, lassen Sie es mich wissen, wenn es funktioniert):

function myCSS(data) {
    var head = document.head || document.getElementsByTagName("head")[0];
    if(head) {
        if(data && data.constructor == Object) {
            for(var k in data) {
                var selector = k;
                var rules = data[k];

                var allSheets = document.styleSheets;
                var cur = null;

                var indexOfPossibleRule = null,
                    indexOfSheet = null;
                for(var i = 0; i < allSheets.length; i++) {
                    indexOfPossibleRule = findIndexOfObjPropInArray("selectorText",selector,allSheets[i].cssRules);
                    if(indexOfPossibleRule != null) {
                        indexOfSheet = i;
                        break;
                    }
                }

                var ruleToEdit = null;
                if(indexOfSheet != null) {

                    ruleToEdit = allSheets[indexOfSheet].cssRules[indexOfPossibleRule];

                } else {
                    cur = document.createElement("style");
                    cur.type =  "text/css";
                    head.appendChild(cur);
                    cur.sheet.addRule(selector,"");
                    ruleToEdit = cur.sheet.cssRules[0];
                    console.log("NOPE, but here's a new one:", cur);
                }
                applyCustomCSSruleListToExistingCSSruleList(rules, ruleToEdit, (err) => {
                    if(err) {
                        console.log(err);
                    } else {
                        console.log("successfully added ", rules, " to ", ruleToEdit);
                    }
                });
            }
        } else {
            console.log("provide one paramter as an object containing the cssStyles, like: {\"#myID\":{position:\"absolute\"}, \".myClass\":{background:\"red\"}}, etc...");
        }
    } else {
        console.log("run this after the page loads");
    }

};  

fügen Sie dann diese beiden Hilfsfunktionen entweder innerhalb der obigen Funktion oder an einer anderen Stelle hinzu:

function applyCustomCSSruleListToExistingCSSruleList(customRuleList, existingRuleList, cb) {
    var err = null;
    console.log("trying to apply ", customRuleList, " to ", existingRuleList);
    if(customRuleList && customRuleList.constructor == Object && existingRuleList && existingRuleList.constructor == CSSStyleRule) {
        for(var k in customRuleList) {
            existingRuleList["style"][k] = customRuleList[k];
        }

    } else {
        err = ("provide first argument as an object containing the selectors for the keys, and the second argument is the CSSRuleList to modify");
    }
    if(cb) {
        cb(err);
    }
}

function findIndexOfObjPropInArray(objPropKey, objPropValue, arr) {
    var index = null;
    for(var i = 0; i < arr.length; i++) {
        if(arr[i][objPropKey] == objPropValue) {
            index = i;
            break;
        }
    }
    return index;
}

(Beachten Sie, dass ich in beiden eine for-Schleife anstelle von .filter verwende, da die CSS-Klassen für Stil-/Regellisten nur eine length -Eigenschaft und keine .filter-Methode haben.)

Dann nennen wir es:

myCSS({
    "#coby": {
        position:"absolute",
        color:"blue"
    },
    ".myError": {
        padding:"4px",
        background:"salmon"
    }
})

Lassen Sie mich wissen, ob es für Ihren Browser funktioniert oder einen Fehler ergibt.

0
bluejayke

Zum Nutzen der Suchenden; Wenn Sie jQuery verwenden, können Sie Folgendes tun:

var currentOverride = $('#customoverridestyles');

if (currentOverride) {
 currentOverride.remove();
}

$('body').append("<style id=\"customoverridestyles\">body{background-color:pink;}</style>");

Natürlich können Sie die innere CSS zu beliebigem ändern.

Ich schätze, dass einige Leute reines JavaScript bevorzugen, aber es funktioniert und war ziemlich robust für das dynamische Schreiben/Überschreiben von Styles.

0
HockeyJ