Javascript 文档样式表使用伪选择器获取元素上的所有样式

Javascript 文档样式表使用伪选择器获取元素上的所有样式,javascript,html,jquery,Javascript,Html,Jquery,根据这个,我得到了所有的元素样式 home.html <div id="divClass" class="myclass">Text Here</div> script.js function copyComputedStyle(a) { var sheets = document.styleSheets, o = {}; for (var i in sheets) { var rule

根据这个,我得到了所有的元素样式

home.html

<div id="divClass" class="myclass">Text Here</div>
script.js

  function copyComputedStyle(a) {
    var sheets = document.styleSheets,
      o = {};
    for (var i in sheets) {
      var rules = sheets[i].rules || sheets[i].cssRules;
      for (var r in rules) {
        if (a.is(rules[r].selectorText)) {
          o = $.extend(o, css2json(rules[r].style), css2json(a.attr('style')));
        }
      }
    }
    return o;
  }

  function css2json(css) {
    var s = {};
    var pattern = /^[1-9][0-9]?$|^100$/;
    if (!css) return s;
    if (css instanceof CSSStyleDeclaration) {
      for (var i in css) {
        if (css[i].toLowerCase) {
          // Some of the key value pairs were vice versa, so try to make them in order!
          // Ex:    0:flex-grow;  0:flex-shrink;  --------> flex-grow: 0; flex-shrink: 0;
          // End
          if (pattern.test(css[i])) {
            s[css[css[i]].toLowerCase()] = css[i];
          } else {
            s[css[i].toLowerCase()] = css[css[i]];
          }
        }
      }
    } else if (typeof css == 'string') {
      css = css.split('; ');
      for (var i in css) {
        var l = css[i].split(': ');
        s[l[0].toLowerCase()] = l[1];
      }
    }
    return s;
  }

console.log(copyComputedStyle($("#divClass")));
它返回一个对象

{
   background-color: "black",
   color: "red",
   float: "left",
   left: ""
}
现在,当我将任何伪选择器悬停或前后添加到此div时,copyComputedStyle不会记录添加的样式并返回与之前相同的样式

#divClass{    
   color:red; 
   background-color:black;
   float:left;
}
#divClass:hover{    
   color:blue; 
} 
如何克服这个问题?

问题在于使用.is时,尤其是当divClass与divClass:hover不匹配时

一种解决方案是使用indexOf确保找到与元素ID匹配的选择器:

更改此选项:如果a.isrules[r],请选择OrText{

为此:if规则[r].selectorText&&rules[r].selectorText.indexOfa.attr'id'!=-1{

如果在代码中更改该行,它将返回如下内容:

{
   background-color: "black",
   color: "blue",
   float: "left",
   left: ""
}
这是因为对象中存在重复的颜色属性,而后者占主导地位,我个人会做的是将每个选择器的样式分组为一个对象:

 function copyComputedStyle(a) {
    var sheets = document.styleSheets,
        o = {},
        objrules = [];

    for (var i in sheets) {
      var rules = sheets[i].rules || sheets[i].cssRules;
      
      for (var r in rules) {
        if (rules[r].selectorText && rules[r].selectorText.indexOf(a.attr('id')) != -1) {
          o = $.extend({},css2json(rules[r].style));
          objrules.push({'selector' : [rules[r].selectorText], 'style' : o});
        }
      }
    }

    return objrules;
  }

  function css2json(css) {
    var s = {};
    var pattern = /^[1-9][0-9]?$|^100$/;

    if (!css) return s;

    if (css instanceof CSSStyleDeclaration) {
      for (var i in css) {
        if (css[i].toLowerCase) {
          // Some of the key value pairs were vice versa, so try to make them in order!
          // Ex:    0:flex-grow;  0:flex-shrink;  --------> flex-grow: 0; flex-shrink: 0;
          // End
          if (pattern.test(css[i])) {
            s[css[css[i]].toLowerCase()] = css[i];
          } else {
            s[css[i].toLowerCase()] = css[css[i]];
          }
        }
      }
    } else if (typeof css == 'string') {
      css = css.split('; ');
      for (var i in css) {
        var l = css[i].split(': ');
        s[l[0].toLowerCase()] = l[1];
      }
    }
    
    return s;
  }

console.log(copyComputedStyle($("#divClass")));

谢谢你的回答,但是有一个小问题->objrules.selector获取正确的选择器,但是objrules.style没有任何内容!它是空的!是的,我得到了…只需更改o=$.extend{},css2jsonrules[r]。selectorText,rules[r]。style;to o=$.extend{},css2jsonrules[r].style;。非常感谢!是的,我正要写这篇文章,哈哈哈,我很高兴它能帮上忙。很抱歉,我有一个简单的问题,我怎么能选择我自己的风格,因为我有引导和字体很棒的CDN链接???工作表存储在sheets变量中,我看到它也包括引导样式,也许我会使用类似sheets[I]的东西.href.indexOf bootstrap从CDN捕获样式,或者有一种更快的方法
 function copyComputedStyle(a) {
    var sheets = document.styleSheets,
        o = {},
        objrules = [];

    for (var i in sheets) {
      var rules = sheets[i].rules || sheets[i].cssRules;
      
      for (var r in rules) {
        if (rules[r].selectorText && rules[r].selectorText.indexOf(a.attr('id')) != -1) {
          o = $.extend({},css2json(rules[r].style));
          objrules.push({'selector' : [rules[r].selectorText], 'style' : o});
        }
      }
    }

    return objrules;
  }

  function css2json(css) {
    var s = {};
    var pattern = /^[1-9][0-9]?$|^100$/;

    if (!css) return s;

    if (css instanceof CSSStyleDeclaration) {
      for (var i in css) {
        if (css[i].toLowerCase) {
          // Some of the key value pairs were vice versa, so try to make them in order!
          // Ex:    0:flex-grow;  0:flex-shrink;  --------> flex-grow: 0; flex-shrink: 0;
          // End
          if (pattern.test(css[i])) {
            s[css[css[i]].toLowerCase()] = css[i];
          } else {
            s[css[i].toLowerCase()] = css[css[i]];
          }
        }
      }
    } else if (typeof css == 'string') {
      css = css.split('; ');
      for (var i in css) {
        var l = css[i].split(': ');
        s[l[0].toLowerCase()] = l[1];
      }
    }
    
    return s;
  }

console.log(copyComputedStyle($("#divClass")));