Получить значение свойства CSS элемента (ширина/высота) по мере его установки (в процентах/em/px/etc)
Как можно получить свойство CSS элементов (например, width/height), поскольку оно было задано с помощью правил CSS, в любых единицах, которые были установлены (например,%/em/px)? (В Google Chrome, предпочтительно без рамки).
Использование 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
как 50%
(и первый как 100px
).
Инспектор элементов Chrome может отображать значение свойства CSS, поскольку они были установлены, поэтому это должно быть возможно в Chrome.
![Chrome element inspector showing property value as they were set]()
Не точный дубликат связанного вопроса, так как там принятый ответ есть простой хак, который производит процентную ширину независимо от того, какая ширина установлена. А для остальных вам нужно знать селектор, используемый для создания активного правила? Как узнать это?
Ответы
Ответ 1
Хорошая новость! Кажется, есть CSS Typed OM на своем пути в черновиках w3.
Быстрое чтение этого документа, кажется, что целью этой, возможно, быть спецификации, является облегчение доступа к значениям CSSOM из javascript.
Очень важная часть этого для нас здесь заключается в том, что у нас будет CSSUnitValue API, который сможет анализировать значения CSS для объекта формы
{
value: 100,
unit: "percent", // | "px" | "em" ...
type: "percent" // | "length"
}
И метод Window.getComputedStyleMap()
, из которого мы сможем получить значения, фактически применяемые к нашим элементам.
На сегодняшний день кажется, что Chrome только начал его реализовывать, и вам нужно включить флаг функций Experimental Web Platform в about:flags
...
(() => {
if (!window.getComputedStyleMap && !Element.prototype.computedStyleMap) {
console.error("Your browser doesn't support CSS Typed OM");
return;
}
document.querySelectorAll('.test')
.forEach((elem) => {
let styleMap;
// As defined in specs' drafts
if (window.getComputedStyleMap) {
styleMap = window.getComputedStyleMap(elem);
}
// Currently Chrome attaches it to the Element proto
else styleMap = elem.computedStyleMap();
const widthValue = styleMap.get('width');
console.log(elem, widthValue);
});
/* outputs
<div class="b test">first</div>
CSSUnitValue {
"type": "length",
"unit": "px",
"value": 100,
[__proto__]
}
<div id="a" class="a test">second</div>
CSSUnitValue {
"type": "percent",
"unit": "percent",
"value": 50,
[__proto__]
}
*/
})();
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>
Ответ 2
Это не так просто, как просто вызов WebKits getMatchedCSSRules()
, он возвращает согласованные правила в порядке приоритета (хотя я не видел упоминания этого порядка в документах), но заказ не учитывает свойство важный приоритет и не включает стили элементов. Поэтому я закончил эту функцию:
getMatchedStyle
function getMatchedStyle(elem, property){
// element property has highest priority
var val = elem.style.getPropertyValue(property);
// if it 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)
Ответ 3
По-видимому, для этого
нет DOM API.
https://developer.mozilla.org/en/DOM/window.getComputedStyle#Notes
EDIT: oops, просто понял, что это было отмечено для Google Chrome
Попробуйте window.getMatchedCSSRules()
Ответ 4
Там более новый дубликат сообщения с отличным ответом здесь. Этот ответ был для 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;
}