2

例如,我可能有一些看起来像这样的 CSS 内容:

.divType1 {
    position: absolute;
    width: 60px; height: 60px;
    left: 400px; top: 100px;
    border: 1px solid #89B;
    z-index: 0;
 }

现在在 Javascript 中,我想收集 div 类 divType1' css 属性,但只提供 div 类,所以我不能做一些形式(伪代码):

selectDivWithClass( divType1 ).getCss(left). 

我可以通过使用类 divType1 实例化一个 div 并获取它的 css 属性来破解某些东西,然后销毁它,但是有更好的方法吗?


最初的问题有一些模棱两可,导致很多好的答案可以在其他环境中使用。所以这里是重述的一个:

使用 Javascript,我如何收集样式表中制造商指定的 div 类的 css 属性的子集,因此没有浏览器默认值。此外,假设只有“plain-vanilla”属性会出现在 css 中。所以像宽度,高度这样的东西,而不是像这样的东西:

transition: width 2s;
-moz-transition: width 2s; /* Firefox 4 */
-webkit-transition: width 2s; /* Safari and Chrome */
-o-transition: width 2s; /* Opera */

我只得到了类名,所以我没有得到我需要事先收集的属性列表。

最后,理想情况下,该函数应将对象映射样式属性返回给值。

在我尝试做的范围内,@RobG 在下面的回答解决了这个问题。

4

5 回答 5

3

您可以遍历document.styleSheets,但不一定比使用该类实例化 DocumentFragment 并获取其属性更快:

var stylesheets = document.styleSheets;
for (var i=0; i < stylesheets.length; i++) {
    var rules = stylesheets[i].cssRules || stylesheets[i].rules;
    for (var j=0, rule; rule = rules[j++]; ) {
        if (rule.selectorText === '.divType1') {
            alert(rule.style.left)
        }
    }
}

小提琴:http: //jsfiddle.net/dandv/VnCMR/1/

于 2012-11-11T22:39:35.013 回答
1

您可以将其添加到 div 然后检查详细信息?这在 jQuery 中运行良好,不幸的是,等效的 javascript 在样式对象中不包含基于类的样式。所以:

var d = $("<div>").addClass("divType1");
console.log(d.css("left"));

将在 jQuery 中工作。这在 JS 中不会:

var d = document.createElement("div");
d.className = "divType1";
console.log(d.style.left);
于 2012-11-11T22:34:21.317 回答
1

你很容易在这里进入跨浏览器地狱。

如果您有一个现有元素(可以使用已经提到的文档片段创建),那么有效的方法(至少在 chrome 中)是

var el = document.getElementsByClassName("divType1")[0];
alert(window.getComputedStyle(el).getPropertyValue("left"));

但是看看这个,你可能会选择在这里使用像 jQuery 这样的 javascript 库。

于 2012-11-11T22:40:14.793 回答
1

这为您提供了第一个样式表中的所有文本

document.styleSheets[0].ownerNode.innerHTML

虽然此函数接受选择器字符串并应返回其文本值

function getStyleBySelector(selector) {
    var sheets = document.styleSheets;
    var selectorRule = false;

    for(var x = 0; x < sheets.length; x++) {
        var rules = sheets[x].cssRules;
        for(var y = 0; y < rules.length; y++) {
            if(rules[y].selectorText == selector) {
                selectorRule = rules[y]
                break;
            }
        }

        if(selectorRule) {
            break;
        }
    }

    var styling = {};

    if(selectorRule) {
        return selectorRule.cssText
    }

    return styling;
}

在你的情况下调用它

getStyleBySelector(".divType1");
于 2012-11-11T23:00:55.477 回答
1

除非您可以过滤掉所有其他规则和默认属性的影响(在不同的浏览器中可能不同,但在某些浏览器中可能与规则属性相同,但在其他浏览器中可能与规则属性相同),否则检查应用了规则的元素将不起作用. 在默认配置中,这似乎不太可能在超过一两个浏览器中成功。

要以跨浏览器的方式将 CSS 规则文本作为文本获取,请使用以下内容:

function getCssRule(selector) {
  var sheets = document.styleSheets;
  var rulesObj, rules, ruleText;

  if (sheets.length) {

    // Determine the name of the rules object
    rulesObj = typeof sheets[0].cssRules != 'undefined'? 'cssRules' : 'rules';

    for (var i=0, iLen=sheets.length; i<iLen; i++) {
      rules = sheets[i][rulesObj];

      for (var j=0, jLen=rules.length; j<jLen; j++) {
        if (rules[j].selectorText.indexOf(selector) > -1) {
          return rules[j].cssText;
        }
      }
    }
  }
}

请注意,这将返回规则的实际文本。

此外,还有一个CSSValue属性,但我不确定是否支持。

编辑

如果你只处理规则部分而不是选择器,你应该能够使用类似的东西把它变成一个对象:

function cssTextToObj(cssText) {

  // Trim selector, initial { and closing } plus whitespace, split on ';'
  var props = cssText.replace(/^[^{]+{\s*/,'').replace(/\s*}\s*$/,'').split(';');
  var resultObj = {};
  var bits;

  for (var i=0, iLen=props.length; i<iLen; i++) {

    // Split each property assignment on ':' only where
    // props[i] has a value
    if (props[i] != '') {
      bits = props[i].split(':');
      resultObj[bits[0]] = bits[1];
    }
  }
  return resultObj;
}

您可能想要修剪前导和尾随空格的属性名称和值,但这应该可行。我不是 CSS 属性方面的专家,所以上面可能需要一些调整。

请注意,如果有尾随';' (如果原始规则没有,浏览器似乎会添加),最后一个成员props将是 '' (空字符串)。

您绝对无法保证的一件事是属性的顺序,而不是您可以知道for..in无论如何都会返回它们的顺序。IE 似乎以cssText自己的顺序返回,Firefox 似乎保持原来的顺序。

于 2012-11-12T00:34:16.657 回答