简体   繁体   English

除了className之外,我如何收集一个类'css属性?

[英]How do I gather a class' css attributes given nothing but the className?

For example I might have some css stuff that looks like this: 例如,我可能有一些看起来像这样的CSS东西:

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

Now within Javascript I want to gather div class divType1' css attributes, but am provided only with the div class, so I can't do something of form ( pseudo-code ): 现在在Javascript中我想收集div类divType1'css属性,但是我只提供了div类,所以我不能做一些表单(伪代码):

selectDivWithClass( divType1 ).getCss(left). 

I could hack something by instantiating a div with class divType1 and grab its css attributes, and then destroy it, but is there a better way? 我可以通过使用类divType1实例化div并获取其css属性来破解它,然后销毁它,但是有更好的方法吗?


The original question has some ambiguity, resulting in lots of good answers that will work in other settings. 最初的问题有些含糊不清,导致许多好的答案可以在其他设置中使用。 So here's the restated one: 所以这是重述的:

Using Javascript, how do I gather a subset of a div class' css attributes specified by the maker in the stylesheet, so no browser defaults. 使用Javascript,如何在样式表中收集由制造商指定的div类的css属性的子集,因此没有浏览器默认值。 Furthermore, assume only 'plain-vanilla' attributes will appear in the css. 此外,假设只有'普通香草'属性会出现在CSS中。 So stuff like width, height, not stuff like: 所以宽度,高度等东西不像:

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

I am given nothing but the class name, so I am not given a list of attributes I need to collect before hand. 除了班级名字,我什么都没有给,所以我没有给出我需要事先收集的属性列表。

Finally, the function ideally should return an object mapping style attribute to value. 最后,理想情况下,函数应该将对象映射样式属性返回给value。

In the scope of what I am trying to do, the problem is solved by @RobG's answer below. 在我想要做的范围内,问题由@ RobG的答案解决

You could iterate through document.styleSheets , but that many not necessarily be faster than instantiating a DocumentFragment with that class and getting its attributes: 您可以遍历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)
        }
    }
}

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

You could add it to a div and then check the details? 您可以将其添加到div中,然后检查详细信息? This works well in jQuery, unfortunately the javascript equivalent doesn't include the class based styles in the style object. 这在jQuery中运行良好,遗憾的是javascript等价物不包括样式对象中基于类的样式。 So: 所以:

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

would work in jQuery. 可以在jQuery中工作。 This in JS wont: 这在JS不会:

var d = document.createElement("div");
d.className = "divType1";
console.log(d.style.left);

You easily come into cross browser hell here. 您可以在这里轻松进入跨浏览器地狱。

What works (at least in chrome) IF you have an existing element (which can be created using document fragment as already mentioned) is 如果您有一个现有元素(可以使用已提到的文档片段来创建),那么有效的方法(至少在chrome中)是:

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

But looking at this you might opt for using a javascript library like jQuery here. 但是看看这个你可能会选择在这里使用像jQuery这样的javascript库。

This gives you all text in first stylesheet 这将为您提供第一个样式表中的所有文本

document.styleSheets[0].ownerNode.innerHTML

While this function accepts a selector string and should return its text value 虽然此函数接受选择器字符串并应返回其文本值

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;
}

In your case call it with 在你的情况下调用它

getStyleBySelector(".divType1");

Inpsecting an element that has the rule applied to it won't work unless you can filter out the effects of all other rules and default properties (which might be different in different browsers and be the same as a rule property in some but not others). 除非您可以过滤掉所有其他规则和默认属性的效果(在不同浏览器中可能不同,并且与某些规则中的规则属性相同但不是其他规则属性),否则不会对已应用规则的元素进行操作。 。 That seems unlikely to be successful in more than one or two browsers in their default configurations. 在默认配置中,这似乎不太可能在一个或两个以上的浏览器中成功。

To get the CSS rule text as text in a cross-browser fashion, use something like: 要以跨浏览器方式将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;
        }
      }
    }
  }
}

Note that this will return the actual text of the rule. 请注意,这将返回规则的实际文本。

Also, there is a CSSValue property, but I am unsure of support. 此外,还有一个CSSValue属性,但我不确定是否支持。

Edit 编辑

If you are dealing only with the rules part and not the selector, you should be able to turn it into an object using something like: 如果只处理规则部分而不是选择器,则应该可以使用以下方法将其变成对象:

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;
}

You may want to trim the property names and values of leading and trailing spaces, but that should work. 您可能希望修剪前导和尾随空格的属性名称和值,但这应该有效。 I'm no expert on CSS properties though, so the above may need some tweaking. 我不是CSS属性的专家,所以上面可能需要一些调整。

Note that if there is a trailing ';' 请注意,如果有一个尾随';' (which browsers seem to add if the original rule didn't have one), the last member of props will be '' (empty string). (如果原始规则没有,则哪些浏览器似乎添加), props的最后一个成员将是''(空字符串)。

One thing you absolutely can't guarantee is the order that properties will be in, not that you can know what order for..in will return them in anyway. 你绝对不能保证的一件事是属性的顺序,而不是你可以知道什么顺序for..in将以任何方式返回它们。 IE seems to return cssText in its own order, Firefox seems to preserve the original order. IE似乎按照自己的顺序返回cssText ,Firefox似乎保留了原始顺序。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM