[javascript] 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;
    }