Получить значение CSS с помощью JavaScript

200

Я знаю, что могу установить значение CSS через JavaScript, например:

document.getElementById('image_1').style.top = '100px';

Но можно ли получить текущее конкретное значение стиля? Я прочитал, где я могу получить весь стиль для элемента, но я не хочу анализировать всю строку, если мне не нужно.

Майкл Пол
источник
Какую «особую ценность стиля» вы пытаетесь получить?
BryanH
текущие значения позиционирования: высота, ширина, вершина, поля и т. д.
Майкл Пол
2
Ваш вопрос позволяет предположить, что вы хотите что-то вроде того, var top = document.getElementById('image_1').style.top; Возможно, захотите перефразировать это, если это не то, что вы хотите
Марк
Спасибо всем, оба метода работают отлично, как раз то, что мне нужно. Метод Jquery немного более компактен, поэтому я, вероятно, буду его использовать.
Майкл Пол

Ответы:

359

Вы можете использовать getComputedStyle().

var element = document.getElementById('image_1'),
    style = window.getComputedStyle(element),
    top = style.getPropertyValue('top');

jsFiddle .

Алекс
источник
10
Например, если вы хотите изменить цвет фона div, будьте осторожны, НЕ ИСПОЛЬЗУЙТЕ «backgroundColor» вместо «backgroung-color»;)
baptx
4
SLW это аббревиатура или ты имел ввиду медленный?
Дэвид Винецки
3
getComputedStyle не поддерживается в IE 8 и ниже.
Дэвид Винецки
6
Несколько не по теме: некоторые (все?) Сокращенные свойства css недоступны в JavaScript. Например, вы можете получить отступ слева, но не отступ. JSFiddle
Дэвид Винецки
4
@DavidWiniecki Я действительно не верю, что webdevs все еще должен считать IE8 основным браузером. учитывая, что это больше не поддерживается Microsoft
Кевин Кюйл
23

Свойство element.style позволяет вам знать только те свойства CSS, которые были определены как встроенные в этом элементе (программно или определены в атрибуте style элемента), вы должны получить вычисляемый стиль.

Это не так просто сделать кросс-браузерным способом, IE имеет свой собственный путь через свойство element.currentStyle, а стандартный способ DOM Level 2, реализованный другими браузерами, - через метод document.defaultView.getComputedStyle.

Два способа имеют различия, например, свойство IE element.currentStyle предполагает, что вы обращаетесь к именам свойств CSS, состоящим из двух или более слов в camelCase (например, maxHeight, fontSize, backgroundColor и т. Д.), Стандартный способ ожидает свойства с слова, разделенные тире (например, максимальная высота, размер шрифта, цвет фона и т. д.). ......

function getStyle(el, styleProp) {
    var value, defaultView = (el.ownerDocument || document).defaultView;
    // W3C standard way:
    if (defaultView && defaultView.getComputedStyle) {
        // sanitize property name to css notation
        // (hyphen separated words eg. font-Size)
        styleProp = styleProp.replace(/([A-Z])/g, "-$1").toLowerCase();
        return defaultView.getComputedStyle(el, null).getPropertyValue(styleProp);
    } else if (el.currentStyle) { // IE
        // sanitize property name to camelCase
        styleProp = styleProp.replace(/\-(\w)/g, function(str, letter) {
            return letter.toUpperCase();
        });
        value = el.currentStyle[styleProp];
        // convert other units to pixels on IE
        if (/^\d+(em|pt|%|ex)?$/i.test(value)) { 
            return (function(value) {
                var oldLeft = el.style.left, oldRsLeft = el.runtimeStyle.left;
                el.runtimeStyle.left = el.currentStyle.left;
                el.style.left = value || 0;
                value = el.style.pixelLeft + "px";
                el.style.left = oldLeft;
                el.runtimeStyle.left = oldRsLeft;
                return value;
            })(value);
        }
        return value;
    }
}

Основной эталонный стек

Амир Мовахеди
источник
16

Кросс-браузерное решение для проверки значений CSS без манипуляций с DOM:

function get_style_rule_value(selector, style)
{
 for (var i = 0; i < document.styleSheets.length; i++)
 {
  var mysheet = document.styleSheets[i];
  var myrules = mysheet.cssRules ? mysheet.cssRules : mysheet.rules;

  for (var j = 0; j < myrules.length; j++)
  {
   if (myrules[j].selectorText && myrules[j].selectorText.toLowerCase() === selector)
   {
    return myrules[j].style[style];
   }
  }
 }
};

Использование:

get_style_rule_value('.chart-color', 'backgroundColor')

Обеззараженная версия (переводит селекторный ввод в нижний регистр и позволяет использовать регистр без начального ".")

function get_style_rule_value(selector, style)
{
 var selector_compare=selector.toLowerCase();
 var selector_compare2= selector_compare.substr(0,1)==='.' ?  selector_compare.substr(1) : '.'+selector_compare;

 for (var i = 0; i < document.styleSheets.length; i++)
 {
  var mysheet = document.styleSheets[i];
  var myrules = mysheet.cssRules ? mysheet.cssRules : mysheet.rules;

  for (var j = 0; j < myrules.length; j++)
  {
    if (myrules[j].selectorText)
    {
     var check = myrules[j].selectorText.toLowerCase();
     switch (check)
     {
      case selector_compare  :
      case selector_compare2 : return myrules[j].style[style];
     }
    }
   }
  }
 }
karolf
источник
У меня был длинный день, и это не сработало по ряду причин. pastie.org/9754599 работает намного лучше, выбрасывая недопустимые списки правил и закрывая обе стороны финала ===. Большое спасибо, ваше решение все же спасло день!
Ричард Фокс
хороший ответ, в конце добавлена ​​продезинфицированная версия, чтобы исправить некоторые крайние проблемы использования.
несинхронизировано
7

Если вы установите его программно, вы можете просто назвать его как переменную (т.е. document.getElementById('image_1').style.top). В противном случае вы всегда можете использовать jQuery:

<html>
    <body>
        <div id="test" style="height: 100px;">Test</div>
        <script type="text/javascript" src="jquery.min.js"></script>
        <script type="text/javascript">
            alert($("#test").css("height"));
        </script>
    </body>
</html>
adotout
источник
7
Я не думаю, что ваш пример jQuery очень ясен (или правильный).
Алекс
свойство style возвращает все встроенные стили, применяемые к элементу, не определенные правилами CSS.
Стивен Кох
3

В 2020 году

проверьте перед использованием

Вы можете использовать computedStyleMap ()

Ответ верен, но иногда вам нужно проверить, какую единицу он возвращает, вы можете получить его без каких-либо slice()или substring()строки.

var element = document.querySelector('.js-header-rep');
element.computedStyleMap().get('padding-left');

var element = document.querySelector('.jsCSS');
var con = element.computedStyleMap().get('padding-left');
console.log(con);
.jsCSS {
  width: 10rem;
  height: 10rem;
  background-color: skyblue;
  padding-left: 10px;
}
<div class="jsCSS"></div>

Нишарг Шах
источник
2

Если вы в библиотеках, почему бы не MyLibrary и getStyle .

Метод jQuery css назван неправильно, CSS является лишь одним из способов установки стилей и не обязательно представляет фактические значения свойств стиля элемента.

RobG
источник
1

В целях безопасности вы можете проверить, существует ли элемент, прежде чем пытаться читать с него. Если он не существует, ваш код выдаст исключение, которое остановит выполнение остальной части вашего JavaScript и потенциально отобразит сообщение об ошибке пользователю - не хорошо. Вы хотите быть в состоянии изящно потерпеть неудачу.

var height, width, top, margin, item;
item = document.getElementById( "image_1" );
if( item ) {
  height = item.style.height;
  width = item.style.width;
  top = item.style.top;
  margin = item.style.margin;
} else {
  // Fail gracefully here
}
BryanH
источник
5
Это плохая идея, если только вы действительно не ожидаете, что узел может отсутствовать в DOM. Слепые нулевые проверки, когда нулевое значение не ожидается, могут привести к появлению ошибок, но, скорее всего, они скрывают ошибку. Если вы ожидаете, что узел будет там, не кодируйте его, так как он не существует, пусть возникнет ошибка, чтобы вы могли исправить свой код. Этот ответ не имеет ничего общего с самим вопросом, и, поскольку он является скорее (плохим) предложением, он должен быть комментарием.
Хуан Мендес
2
Спасибо за ваш комментарий. Я делаю это, потому что я склонен развиваться в обороне. Вот вопрос: как бы вы увидели ошибку на компьютере пользователя? Помните, что то, что работает для вас на вашем компьютере, может не работать для других (различные браузеры и операционные системы, плагины, которые влияют на поведение страницы, различные другие отключенные функции и т. Д.). Смысл был в том, чтобы сделать это изящно, чтобы страница все еще делала что-то близкое к тому, что было задумано, вместо того, чтобы показывать пользователю бесполезную ошибку.
BryanH
@BryanH Есть ошибка браузера, когда он не отображает элемент с идентификатором «image_1»? ;)
alex
@alex Нет. Если нет элемента с таким идентификатором, то код OP потерпит неудачу с ошибкой. Пример . Мое предложение состояло в том, чтобы закодировать, чтобы это никогда не могло произойти.
BryanH
0

Кросс-браузерное решение без DOM-манипуляции, приведенное выше, не работает, потому что оно дает первое правило соответствия, а не последнее. Последнее правило соответствия является тем, которое применяется. Вот рабочая версия:

function getStyleRuleValue(style, selector) {
  let value = null;
  for (let i = 0; i < document.styleSheets.length; i++) {
    const mysheet = document.styleSheets[i];
    const myrules = mysheet.cssRules ? mysheet.cssRules : mysheet.rules;
    for (let j = 0; j < myrules.length; j++) {
      if (myrules[j].selectorText && 
          myrules[j].selectorText.toLowerCase() === selector) {
        value =  myrules[j].style[style];
      }
    }
  }
  return value;
}  

Однако этот простой поиск не будет работать в случае сложных селекторов.

jcdufourd
источник