[html] JavaScript로 CSS 규칙 값을 어떻게 읽습니까?

인라인 스타일에서 볼 수있는 형식과 같이 CSS 규칙의 모든 내용이 포함 된 문자열을 반환하고 싶습니다. 특정 규칙에 포함 된 내용을 알지 못해도이 작업을 수행 할 수 있기를 원하므로 스타일 이름 (예 : .style.width등)으로 만 빼낼 수 없습니다 .

CSS :

.test {
    width:80px;
    height:50px;
    background-color:#808080;
}

지금까지 코드 :

function getStyle(className) {
    var classes = document.styleSheets[0].rules || document.styleSheets[0].cssRules
    for(var x=0;x<classes.length;x++) {
        if(classes[x].selectorText==className) {
            //this is where I can collect the style information, but how?
        }
    }
}
getStyle('.test')



답변

여기 에서 수정 하여 scunliffe의 답변을 기반으로합니다.

function getStyle(className) {
    var cssText = "";
    var classes = document.styleSheets[0].rules || document.styleSheets[0].cssRules;
    for (var x = 0; x < classes.length; x++) {
        if (classes[x].selectorText == className) {
            cssText += classes[x].cssText || classes[x].style.cssText;
        }
    }
    return cssText;
}

alert(getStyle('.test'));


답변

“nsdel”에서 받아 들여진 답변은 문서에있는 하나의 스타일 시트에서만 사용할 수 있기 때문에 이것은 조정 된 전체 작업 솔루션입니다.

    /**
     * Gets styles by a classname
     *
     * @notice The className must be 1:1 the same as in the CSS
     * @param string className_
     */
    function getStyle(className_) {

        var styleSheets = window.document.styleSheets;
        var styleSheetsLength = styleSheets.length;
        for(var i = 0; i < styleSheetsLength; i++){
            var classes = styleSheets[i].rules || styleSheets[i].cssRules;
            if (!classes)
                continue;
            var classesLength = classes.length;
            for (var x = 0; x < classesLength; x++) {
                if (classes[x].selectorText == className_) {
                    var ret;
                    if(classes[x].cssText){
                        ret = classes[x].cssText;
                    } else {
                        ret = classes[x].style.cssText;
                    }
                    if(ret.indexOf(classes[x].selectorText) == -1){
                        ret = classes[x].selectorText + "{" + ret + "}";
                    }
                    return ret;
                }
            }
        }

    }

주의 : 선택자는 CSS에서와 동일해야합니다.


답변

솔루션 1 (크로스 브라우저)

function GetProperty(classOrId,property)
{
    var FirstChar = classOrId.charAt(0);  var Remaining= classOrId.substring(1);
    var elem = (FirstChar =='#') ?  document.getElementById(Remaining) : document.getElementsByClassName(Remaining)[0];
    return window.getComputedStyle(elem,null).getPropertyValue(property);
}

alert( GetProperty(".my_site_title","position") ) ;

솔루션 2 (크로스 브라우저)

function GetStyle(CLASSname)
{
    var styleSheets = document.styleSheets;
    var styleSheetsLength = styleSheets.length;
    for(var i = 0; i < styleSheetsLength; i++){
        if (styleSheets[i].rules ) { var classes = styleSheets[i].rules; }
        else {
            try {  if(!styleSheets[i].cssRules) {continue;} }
            //Note that SecurityError exception is specific to Firefox.
            catch(e) { if(e.name == 'SecurityError') { console.log("SecurityError. Cant readd: "+ styleSheets[i].href);  continue; }}
            var classes = styleSheets[i].cssRules ;
        }
        for (var x = 0; x < classes.length; x++) {
            if (classes[x].selectorText == CLASSname) {
                var ret = (classes[x].cssText) ? classes[x].cssText : classes[x].style.cssText ;
                if(ret.indexOf(classes[x].selectorText) == -1){ret = classes[x].selectorText + "{" + ret + "}";}
                return ret;
            }
        }
    }
}

alert( GetStyle('.my_site_title') );


답변

알아야 할 몇 가지 브라우저 차이점 :

주어진 CSS :

div#a { ... }
div#b, div#c { ... }

InsDel의 예에서 클래스는 FF에서 2 개의 클래스와 IE7에서 3 개의 클래스를 갖습니다 .

내 예는 이것을 설명합니다.

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
   "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
    <style>
    div#a { }
    div#b, div#c { }
    </style>
    <script>
    function PrintRules() {
    var rules = document.styleSheets[0].rules || document.styleSheets[0].cssRules
        for(var x=0;x<rules.length;x++) {
            document.getElementById("rules").innerHTML += rules[x].selectorText + "<br />";
        }
    }
    </script>
</head>
<body>
    <input onclick="PrintRules()" type="button" value="Print Rules" /><br />
    RULES:
    <div id="rules"></div>
</body>
</html>


답변

다음은 페이지의 모든 규칙을 반복하는 코드입니다.

function iterateCSS(f) {
  for (const styleSheet of window.document.styleSheets) {
    const classes = styleSheet.rules || styleSheet.cssRules;
    if (!classes) continue;

    for (const cssRule of classes) {
      if (cssRule.type !== 1 || !cssRule.style) continue;
      const selector = cssRule.selectorText, style=cssRule.style;
      if (!selector || !style.cssText) continue;
      for (let i=0; i<style.length; i++) {
        const propertyName=style.item(i);
        if (f(selector, propertyName, style.getPropertyValue(propertyName), style.getPropertyPriority(propertyName), cssRule)===false) return;
      }
    }
  }
}

iterateCSS( (selector, propertyName, propertyValue, propertyPriority, cssRule) => {
  console.log(selector+' { '+propertyName+': '+propertyValue+(propertyPriority==='important' ? ' !important' : '')+' }');
});


답변

function getStyle(className) {
    document.styleSheets.item("menu").cssRules.item(className).cssText;
}
getStyle('.test')

참고 : “메뉴”는 CSS를 적용한 요소 ID입니다. “className”은 텍스트를 가져 오는 데 필요한 CSS 클래스 이름입니다.


답변

정말 효과가있는 제안을 찾지 못했습니다. 여기에 클래스를 찾을 때 간격을 정규화하는 더 강력한 것이 있습니다.

//Inside closure so that the inner functions don't need regeneration on every call.
const getCssClasses = (function () {
    function normalize(str) {
        if (!str)  return '';
        str = String(str).replace(/\s*([>~+])\s*/g, ' $1 ');  //Normalize symbol spacing.
        return str.replace(/(\s+)/g, ' ').trim();           //Normalize whitespace
    }
    function split(str, on) {               //Split, Trim, and remove empty elements
        return str.split(on).map(x => x.trim()).filter(x => x);
    }
    function containsAny(selText, ors) {
        return selText ? ors.some(x => selText.indexOf(x) >= 0) : false;
    }
    return function (selector) {
        const logicalORs = split(normalize(selector), ',');
        const sheets = Array.from(window.document.styleSheets);
        const ruleArrays = sheets.map((x) => Array.from(x.rules || x.cssRules || []));
        const allRules = ruleArrays.reduce((all, x) => all.concat(x), []);
        return allRules.filter((x) => containsAny(normalize(x.selectorText), logicalORs));
    };
})();

Chrome 콘솔에서 실행중인 작업입니다.

여기에 이미지 설명 입력