IT

JavaScript로 CSS 클래스를 동적으로 작성하고 적용하는 방법?

lottoking 2020. 3. 27. 08:13
반응형

JavaScript로 CSS 클래스를 동적으로 작성하고 적용하는 방법?


JavaScript로 CSS 스타일 시트 클래스를 동적으로 만들고 div, table, span, tr 등과 같은 일부 HTML 요소와 asp : Textbox, Dropdownlist 및 datalist와 같은 일부 컨트롤에 할당해야합니다.

가능합니까?

샘플로 좋을 것입니다.


JavaScript로 CSS 클래스를 작성하려는 이유는 확실하지 않지만 다음 옵션이 있습니다.

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

모든 브라우저에서 작동 하는 더 나은 솔루션을 찾았습니다 .
document.styleSheet를 사용하여 규칙을 추가하거나 바꿉니다. 허용되는 대답은 짧고 편리하지만 IE8 이하에서도 작동합니다.

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

기능은 다음과 같이 사용됩니다.

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

짧은 대답, 이것은 "모든 브라우저에서"(특히 IE8 / 7) 호환됩니다.

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

그리고이 마지막 비트는 클래스를 요소에 적용합니다.

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

여기 약간의 테스트 페이지가 있습니다 : https://gist.github.com/shadybones/9816763

핵심 요소는 스타일 요소에 규칙을 추가 / 제거하는 데 사용할 수있는 "styleSheet"/ "sheet"속성이 있다는 사실입니다.


CSS 선언을 생성 할 수있는 간단한 jQuery 플러그인이 있습니다 : jQuery-injectCSS

실제로 JSS (JSON에서 설명하는 CSS)를 사용하지만 동적 CSS 스타일 시트를 생성하기 위해 처리하기가 매우 쉽습니다.

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

YUI는 지금까지 내가 본 최고의 스타일 시트 유틸리티를 가지고 있습니다. 나는 당신이 그것을 확인하는 것이 좋지만 여기에 맛이 있습니다.

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

여기에 제안 된 것과 같이 스타일을 변경하는 훨씬 더 간단한 방법이 있습니다. 그들이 당신의 문제에 적합하다면, 그들은 최선일지도 모르지만, CSS를 수정하는 것이 더 나은 해결책 인 이유는 분명히 있습니다. 가장 명백한 경우는 많은 수의 요소를 수정해야하는 경우입니다. 다른 주요 사례는 계단식을 포함하기 위해 스타일을 변경해야하는 경우입니다. dom을 사용하여 요소를 수정하면 항상 우선 순위가 높습니다. 그것의 슬레지 해머 접근법이며 html 요소에서 스타일 속성을 직접 사용하는 것과 같습니다. 항상 원하는 효과는 아닙니다.


IE 9부터 텍스트 파일을로드하고 style.innerHTML 속성을 설정할 수 있습니다. 따라서 본질적으로 ajax를 통해 CSS 파일을로드하고 콜백을 얻은 다음 스타일 태그 안에 텍스트를 설정하면됩니다.

이것은 다른 브라우저에서 작동하지만 얼마나 멀리 있는지 확실하지 않습니다. 그러나 IE8을 지원할 필요가 없으면 작동합니다.

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

그런 다음 myCss.css와 같은 외부 파일을 가져올 수 있습니다

.myClass { background:#F00; }

Vishwanath의 솔루션은 주석으로 약간 다시 작성되었습니다.

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

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

JavaScript에서 CSS 클래스를 동적으로 작성하고 업데이트하는 한 가지 옵션 :

  • 스타일 요소를 사용하여 CSS 섹션 만들기

  • CSS
    클래스를 업데이트 할 수 있도록 스타일 요소에 ID 사용

.....

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)

구글 클로저 사용하기 :

ccsom 모듈을 사용할 수 있습니다.

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

자바 스크립트 코드는 CSS 노드를 문서 헤드에 넣을 때 크로스 브라우저가 되려고합니다.


당신의 작업에서 당신을 도울 수있는 흥미로운 프로젝트는 JSS 입니다.

JSS는 CSS보다 더 나은 추상화입니다. 선언적이고 유지 관리 가능한 방식으로 스타일을 설명하는 언어로 JavaScript를 사용합니다. 브라우저 및 서버 측에서 런타임에 작동하는 고성능 JS to CSS 컴파일러입니다.

JSS 라이브러리를 사용하면 .attach()함수를 사용하여 DOM / 헤드 섹션에 삽입 할 수 있습니다 .

평가를위한 Repl 온라인 버전 .

JSS에 대한 추가 정보 .

예를 들면 :

// 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()

답을 살펴 보았고 가장 명백하고 직접적인 내용이 누락되었습니다. document.write()필요한 CSS 덩어리를 작성하는 데 사용하십시오.

다음은 예입니다 (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>

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

검색 자의 이익을 위해; jQuery를 사용하는 경우 다음을 수행 할 수 있습니다.

var currentOverride = $('#customoverridestyles');

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

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

분명히 내부 CSS를 원하는대로 변경할 수 있습니다.

일부 사람들은 순수한 JavaScript를 선호하지만, 작동하고 스타일을 동적으로 쓰거나 덮어 쓰는 데 매우 강력합니다.


나는 여기에 대한 답변 중 일부를 살펴 보았고 새로운 스타일 시트가 없으면 자동으로 새 스타일 시트를 추가하는 것을 찾을 수 없었으며 이미 필요한 스타일을 포함하는 기존 스타일을 수정하지 않으면 새로운 기능을 만들었습니다 ( 테스트하지는 않았지만 addRule을 사용하는 모든 브라우저에서 작동해야하며 기본 기본 JavaScript 외에도 작동하는지 알려주세요).

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

};  

그런 다음 위의 함수 내부 또는 다른 곳에이 두 도우미 함수를 추가하십시오.

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

CSS 스타일 / 규칙 목록 클래스에는 길이 속성 만 있고 .filter 메서드는 없기 때문에 둘 다 .filter 대신 for 루프를 사용합니다.

그런 다음 호출하십시오.

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

브라우저에서 작동하거나 오류가 발생하면 알려주십시오.

참고 URL : https://stackoverflow.com/questions/1720320/how-to-dynamically-create-css-class-in-javascript-and-apply

반응형