Получить значение свойства CSS элемента (ширина / высота) в том виде, в котором оно было задано (в процентах / em / px / etc) - PullRequest
26 голосов
/ 16 марта 2012

Как можно получить свойство CSS элементов (например, width / height), как оно было установлено с помощью правил CSS, в каких единицах измерения оно было установлено (например, в процентах / em / px)? (В гугл хром желательно без рамок).

Использование getComputedStyle возвращает текущее значение в пикселях, как и css() в jQuery.

Например:

<div class="b">first</div>
<div id="a" class="a">second</div>

<style>
     div      { width: 100px; }
     x, div#a { width: 50%;   }
     .a       { width: 75%;   }
</style>

Итерируя все элементы div в этом примере, я хотел бы иметь возможность получить вторую div s ширину как 50% (а первую как 100px).


Инспектор элементов Chrome может отображать значение свойства CSS в том виде, в котором они были заданы, поэтому это должно быть возможно в Chrome.

Chrome element inspector showing property value as they were set


Не является точной копией связанного вопроса, так как там принятый ответ, есть простой хак, который выдает процент ширины независимо от того, какой тип ширины установлен. А в остальном вы должны знать селектор, используемый для создания активного правила? Откуда это знать?

Ответы [ 4 ]

21 голосов
/ 16 марта 2012

Это не так просто, как простой вызов WebKits getMatchedCSSRules(), он возвращает соответствующие правила в порядке приоритета (хотя я не видел упоминания этого порядка в документации), но порядок не учитывает свойствоважный приоритет и не включает стили элементов.Итак, я закончил с этой функцией:

getMatchedStyle

function getMatchedStyle(elem, property){
    // element property has highest priority
    var val = elem.style.getPropertyValue(property);

    // if it's important, we are done
    if(elem.style.getPropertyPriority(property))
        return val;

    // get matched rules
    var rules = getMatchedCSSRules(elem);

    // iterate the rules backwards
    // rules are ordered by priority, highest last
    for(var i = rules.length; i --> 0;){
        var r = rules[i];

        var important = r.style.getPropertyPriority(property);

        // if set, only reset if important
        if(val == null || important){
            val = r.style.getPropertyValue(property);

            // done if important
            if(important)
                break;
        }
    }

    return val;
}

Пример

Учитывая следующий код и правила стиля:

<div class="b">div 1</div>
<div id="a" class="a d2">div 2</div>
<div id="b" class="b d3" style="width: 333px;">div 3</div>
<div id="c" class="c d4" style="width: 44em;">div 4</div>

<style>
div      { width: 100px; }
.d3      { width: auto !important; }
div#b    { width: 80%;   }
div#c.c  { width: 444px; }
x, div.a { width: 50%;   }
.a       { width: 75%;   }
</style>

этот JSкод

var d = document.querySelectorAll('div');

for(var i = 0; i < d.length; ++i){
    console.log("div " + (i+1) + ":  " + getMatchedStyle(d[i], 'width'));
}

дает следующие значения ширины для div s:

div 1:  100px
div 2:  50%
div 3:  auto
div 4:  44em

( при jsFiddle )

5 голосов
/ 16 марта 2012

Очевидно, что для этого

нет API DOM

https://developer.mozilla.org/en/DOM/window.getComputedStyle#Notes

РЕДАКТИРОВАТЬ: упс, только что понял, что это было отмечено для Google Chrome

Попробуйте window.getMatchedCSSRules ()

3 голосов
/ 07 марта 2018

Хорошие новости всем! Кажется, в черновиках w3c на его пути CSS Typed OM .

При быстром чтении этого документа, похоже, что цель этой , может быть, спецификации , состоит в том, чтобы облегчить доступ к значениям CSSOM из javascript.

Действительно важной частью этого для нас является то, что у нас будет API CSSUnitValue , который сможет анализировать значения CSS для объекта формы

{
  value: 100,
  unit: "percent", // | "px" | "em" ...
  type: "percent"  // | "length"
}

И добавьте метод computedStyleMap() в интерфейс Element, из которого мы сможем получить значения, фактически примененные к нашим элементам.

На сегодняшний день только Chrome реализует его (начиная с 66).

(() => {
  if (!Element.prototype.computedStyleMap) {
    console.error("Your browser doesn't support CSS Typed OM");
    return;
  }
  document.querySelectorAll('.test')
    .forEach((elem) => {
      let styleMap = elem.computedStyleMap();
      const unitvalue = styleMap.get('width');
      console.log(elem, {
        type: unitvalue.type(),
        unit: unitvalue.unit,
        value: unitvalue.value
      });
    });

/* outputs

  <div class="b test">first</div> {
    "type": {
      "length": 1
    },
    "unit": "px",
    "value": 100
  }
  
  <div id="a" class="a test">second</div> {
    "type": {
      "percent": 1
    },
    "unit": "percent",
    "value": 50
  }

*/

})();
div.test {  width: 100px; }
x,div#a {  width: 50%; }
.a {  width: 75%; }
<div class="b test">first</div>
<div id="a" class="a test">second</div>
3 голосов
/ 01 июля 2015

Более новый дубликат с отличным ответом здесь .Этот ответ был для jQuery, но легко реализовать в чистом js .

function getDefaultStyle(element, prop) {
    var parent = element.parentNode,
        computedStyle = getComputedStyle(element),
        value;
    parent.style.display = 'none';
    value = computedStyle.getPropertyValue(prop);
    parent.style.removeProperty('display');
    return value;
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...