如何使用 JavaScript 读取 CSS 规则值?

IT技术 javascript html css
2021-01-21 05:33:37

我想返回一个包含 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')
6个回答

改编自here,基于 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'));
这在chrome中不起作用,但在firefox中起作用,可能是什么问题?
2021-03-22 05:33:37
@Johnydepvar classes应该document.styleSheets[0].rules[0].cssRules在 Chrome 中。这可以(创造性地)添加到答案中的垫片中。
2021-03-22 05:33:37
请注意, className 必须与 CSS 文件中使用的选择器完全匹配。例如,如果样式被描述为“.article a, article a:hover { color: #ccc; }”,则 getStyle(".article a") 将找不到任何内容。
2021-03-28 05:33:37
@surya 请参阅我的答案以获取经过调整的完整工作解决方案
2021-04-02 05:33:37
如果有多个样式表,那么您还需要遍历这些样式表。for(var i=0;i<document.styleSheets.length;i++) { var s = document.styleSheets[i];}
2021-04-07 05:33:37

由于来自“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 中的选择器相同。

有效,但应该返回一个对象而不是一个字符串
2021-03-10 05:33:37
如果样式表没有规则或 cssRules(可能发生!)添加 if (!classes) continue,您的代码将失败;在 var classes = styleSheets[i].rules || 之后 styleSheets[i].cssRules; var classesLength = classes.length; 看我的编辑
2021-03-16 05:33:37
请注意,自 GC 版本 64.0 起这不起作用:stackoverflow.com/questions/48753691/...
2021-03-23 05:33:37
@kofifus 您的方法已添加
2021-03-30 05:33:37
global_ist 只是 window 对象的别名。我已经编辑了代码片段。现在应该可以用了
2021-04-03 05:33:37

解决方案 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') );

我发现没有任何建议可以真正起作用。这是一个更强大的方法,可以在查找类时规范间距。

//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 控制台中的操作。

在此处输入图片说明

我修改了它以使用 IE11(例如 ES5)。这是一个 JSFiddle,里面有你需要的一切:jsfiddle.net/xp5r8961
2021-03-16 05:33:37
这是本页所有答案的机甲。我什至会说这应该在github上
2021-04-03 05:33:37
这在 IE11 中不起作用,因为不支持使用提供的语法的 Array.map()。我建议将其更改为旧的 function(){ return xxx; } 语法以获得更好的兼容性。否则,很好的答案!
2021-04-05 05:33:37

需要注意的一些浏览器差异:

鉴于 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>