【问题标题】:cssRules unable to read multiple stylesheet classes properties valuescssRules 无法读取多个样式表类属性值
【发布时间】:2019-07-14 00:14:47
【问题描述】:

借助这个答案 (get all css classes background & color properties values),我可以获得所有 CSS 类的背景和颜色属性值。当我使用内部 css 代码时它可以工作。

现在,我有超过 35 个外部 CSS 样式表。当我尝试下面的代码时,它只返回第一个外部 CSS 文件输出。无法获取剩余的样式表背景和颜色属性值。如何访问剩余的样式表?

$('#nightMode').on('click', function() {
    // var color = $("body").css("background");
    // var test = invertColor("#00a3fe"); 
    // console.log(color); 

    let styles = document.styleSheets;

    const rgbToHex = (rgbStr) => !rgbStr ? '':'#' + rgbStr
      .slice(4,-1)
      .split(', ')
      .map(x => (+x).toString(16).padStart(2, '0'))
      .join('');

    let cssArr =[...styles[0].cssRules].map(x=> ({
      class: x.selectorText,
      background: rgbToHex(x.style.background),
      color: rgbToHex(x.style.color)
    } ));

    let genCssStr='';
    genCssStr+= '<style> \n\n';
    cssArr.forEach(x=> genCssStr+=`${x.class}{\n` + 
      (x.background ? `  background:${invertColor(x.background)};\n` : '') + 
      (x.color ? `  color:${invertColor(x.color)};\n` : '') + `}\n\n`);
    genCssStr+= '</style>';

    console.log(styles);
    console.log(genCssStr);
    $(genCssStr).appendTo("body");
    // console.log("array:", JSON.stringify(cssArr));
    // console.log("text:\n\n", genCssStr);
});

【问题讨论】:

  • "...现在,我有超过 35 个外部 css 样式表。" 哎呀!我见过最多有 5 到 8 个样式表的臃肿的 CMS 和 WordPuke 网站。您无需为需要压缩和重构的 CSSRules 乱七八糟。
  • 你看过[...styles[0].cssRules]在控制台中的样子吗?看起来很可疑。试试这个:let cssBloatedArray = styles.cssRules 然后[...cssBloatedArray]
  • @zer00ne [...styles[0].cssRules] 它在控制台中返回这个 Array(6) [ CSSFontFaceRule, CSSFontFaceRule, CSSFontFaceRule, CSSFontFaceRule, CSSFontFaceRule, CSSStyleRule ".massitems a" ]
  • @zer00ne let cssBloatedArray = styles.cssRules 然后[...cssBloatedArray] 这个返回TypeError: cssBloatedArray is undefined
  • @zer00ne let cssBloatedArray = styles[0].cssRules 然后[...cssBloatedArray] 这返回Array(6) [ CSSFontFaceRule, CSSFontFaceRule, CSSFontFaceRule, CSSFontFaceRule, CSSFontFaceRule, CSSStyleRule ".massitems a" ]

标签: javascript jquery css arrays stylesheet


【解决方案1】:

主要问题是您只迭代第一个样式表。您需要迭代所有样式表。 另请注意,您不能枚举跨域样式表的cssRules 属性

以下代码处理所有样式表(&lt;link rel&gt;&lt;style&gt;)中的所有 CSS 规则。如果无法访问外部样式表,则添加 try...catch 块以忽略 DOMExceptions:

var cssArr = [];
[...document.styleSheets].forEach(function(styleSheet) {
  var cssRules;
  try {
    cssRules = styleSheet.cssRules;
  } catch (e) {
    console.log("Cannot process " + styleSheet.href);
    return;
  }
  [...cssRules].forEach(function(cssRule) {
    cssArr.push({
      class: cssRule.selectorText,
      background: cssRule.style.background,
      color: cssRule.style.color
    });
  });
});
console.log(cssArr);

【讨论】:

  • 它抛出Cannot Process style.css。有没有办法访问 css 类及其属性?
  • 但是以前,我可以单独获取第一个样式表的 css 类及其属性。
  • 如果“style.css”属于另一个域,例如你的网页是example.com/blog 和样式表来自code.jquery.com/themes/1/styles.css 然后不,没有办法(我知道)。
  • 没有。我所有的样式表都来自同一个域。像 css/main.css、css/style.css、setup.css。我没有任何属于其他域的样式表。
  • 注释掉 try ... catch 并发布您遇到的实际错误。
【解决方案2】:

This answer 描述了某些规则可能无法访问的原因。

总而言之,如果css资源是跨域的,那么安全限制会阻止访问。

此外,在该答案中,this reference 描述了样式表接口并明确声明了上述断言无法访问跨源资源,这适用于 cssRules 以及 @987654323 上的其他一些属性@对象。

以下代码将优雅地捕获该错误并将错误的输出或 cssRule 打印到控制台。

for (let i in [...document.styleSheets]){
    try{
        console.log(styles[i]['cssRules']);
    }catch(e){
        console.log(e);
    }
}    

【讨论】:

    【解决方案3】:

    您只访问第一个外部文件,因为您只使用索引0:styles[0].cssRules。您应该像这样遍历所有文件:

    styles.forEach(style => {
      let cssArr =[...style.cssRules].map(x=> ({ class: x.selectorText, background: rgbToHex(x.style.background), color: rgbToHex(x.style.color)} ));
    })
    

    【讨论】:

    • 它返回Uncaught TypeError: styles.forEach is not a function
    • 你应该在之前添加它:let styles = document.styleSheets;
    • 如果我在let styles = document.styleSheets;之前添加它,它会返回Uncaught ReferenceError: styles is not defined
    • let styles = ... 应该是第一条语句。第二个语句是styles.forEach
    • 然后又抛出Uncaught TypeError: styles.forEach is not a function :-(
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多