以递归方式从元素和所有子元素中获取CSS

时间:2017-12-08 13:38:19

标签: javascript html css

所以我希望能够做到这样的事情:

getRecursiveCSS(document.getElementById('#menubar'))

我希望它能为主要元素和所有孩子返回一串CSS。

这是我尝试的:(不起作用)

function fullPath(el){
  var names = [];
  while (el.parentNode){
    if (el.id){
      names.unshift('#'+el.id);
      break;
    }else{
      if (el==el.ownerDocument.documentElement) names.unshift(el.tagName);
      else{
        for (var c=1,e=el;e.previousElementSibling;e=e.previousElementSibling,c++);
        names.unshift(el.tagName+":nth-child("+c+")");
      }
      el=el.parentNode;
    }
  }
  return names.join(" > ");
}

function styleRecursive(elements, css) {
    elements = Object.prototype.toString.call(elements) === '[object Array]' ? elements: [elements];
    if (elements.length == 0 || typeof elements[0] == 'undefined')
        return css;

    if (typeof elements[0].querySelector == 'undefined')
        return css

    if (typeof css == 'undefined')
        css = fullPath(elements[0]) + '{' + getComputedStyle(elements[0]).cssText + '}';
    else
        css += fullPath(elements[0]) + '{' + getComputedStyle(elements[0]).cssText + '}';

    _elements = [];

    for (var i = 0; i < elements.length; i++) {
        for (var ii = 0; ii < elements[i].childNodes.length; ii++)
            _elements.push(elements[i].childNodes[ii]);
    }

    return styleRecursive(_elements, css);
};

1 个答案:

答案 0 :(得分:3)

我提出了一个解决方案,可能会让您了解如何改进代码。为了测试驱动这段代码,我创建了一个元素,它有一些不同深度的孩子,这段代码以递归的方式遍历所有孩子,以找到/获取他们的css。之后,所有创建的css加上元素名称将存储在对象(JSON之类)中供以后使用。

请注意
1)此代码不是防弹,因此您需要添加许多条件/检查器,以使其适用于所有情况。
2)用铬测试。
3)仅限于查找元素及其子元素的类(易于升级为id和标记支持)

<强>输出

one : {
  display: "block",
  position: "relative"
}
two : {
  display: "inline-block",
  font-family: "Montserrat"
}
three_1 : {
  display: "table",
  position: "absolute",
  left: "0px"
}
four_1 : {
  display: "table-cell",
  position: "relative"
}
three_2 : {
  display: "table",
  position: "absolute",
  right: "0px"
}
four_2 : {
  display: "table-cell",
  position: "relative"
}

<强> HTML (样品):

<div class="one">
    <div class="two">
        <div class="three_1">
            <div class="four_1"></div>
        </div>
        <div class="three_2">
            <div class="four_2"></div>
        </div>
    </div>
</div>

<强> CSS (样品):

.one {display:block;position:relative;}
.two {display:inline-block;font-family:'Montserrat';}
.three_1 {display:table;position:absolute;left:0;}
.three_2 {display:table;position:absolute;right:0;}
.four_1 {display:table-cell;position:relative;}
.four_2 {display:table-cell;position:relative;}

<强> JS

function convertObjlike(css) {
    var s = {};
    if (!css) return s;
    css = css.split("; ");
    for (var i in css) {
        var l = css[i].split(": ");
        s[l[0].toLowerCase()] = (l[1]);
    }
    return s;
}

function getCss(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 === rules[r].selectorText) {
                o = convertObjlike(rules[r].style.cssText);
            }
        }
    }
    return o;
}

var anObject = {};
function styleRecursive(element){
  anObject[element.className] = (getCss('.'+element.className));
  var children = element.children;

  for (var i = 0; i < children.length; i++) {
    styleRecursive(children[i])
  }
}

styleRecursive( document.querySelector('.one') );
console.log(anObject);

Jsfiddle