How to dynamically create CSS class in JavaScript and apply?

后端 未结 15 1022
长情又很酷
长情又很酷 2020-11-22 02:57

I need to create a CSS stylesheet class dynamically in JavaScript and assign it to some HTML elements like - div, table, span, tr, etc and to some controls like asp:Textbox,

相关标签:
15条回答
  • 2020-11-22 03:41

    There is a light jQuery plugin which allows to generate CSS declarations: jQuery-injectCSS

    In fact, it uses JSS (CSS described by JSON), but it's quite easy to handle in order to generate dynamic css stylesheets.

    $.injectCSS({
        "#test": {
            height: 123
        }
    });
    
    0 讨论(0)
  • 2020-11-22 03:41

    Here is Vishwanath's solution slightly rewritten with comments :

    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;
        }
    
    0 讨论(0)
  • 2020-11-22 03:41

    Using google closure:

    you can just use the ccsom module:

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

    The javascript code attempts to be cross browser when putting the css node into the document head.

    0 讨论(0)
  • 2020-11-22 03:43

    As of IE 9. You can now load a text file and set a style.innerHTML property. So essentially you can now load a css file through ajax (and get the callback) and then just set the text inside of a style tag like this.

    This works in other browsers, not sure how far back. But as long as you don't need to support IE8 then it would work.

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

    and then you can have it pull an external file like the myCss.css

    .myClass { background:#F00; }
    
    0 讨论(0)
  • 2020-11-22 03:45

    I was looking through some of the answers here, and I couldn't find anything that automatically adds a new stylesheet if there are none, and if not simply modifies an existing one that already contains the style needed, so I made a new function (should work accross all browsers, though not tested, uses addRule and besides that only basic native JavaScript, let me know if it works):

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

    then just add these 2 helper functions either inside the above function, or anywhere else:

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

    (notice that in both of them I use a for loop instead of .filter, since the CSS style / rule list classes only have a length property, and no .filter method.)

    Then to call it:

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

    Let me know if it works for your browser or gives an error.

    0 讨论(0)
  • 2020-11-22 03:46

    Although I'm not sure why you want to create CSS classes with JavaScript, here is an 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';
    
    0 讨论(0)
提交回复
热议问题