WebKit/Phantomjs, почему вывод getComputedStyles так?

В большинстве браузеров (например, Firefox, Opera) получение вычисленного стиля для элемента, возвращающего хороший объект типа CSSStyleDeclaration, В Chrome 28 и PhantomJS 1.9 я получаю объект, который начинается с нумерованных ключей, перечисляющих все свойства CSS, а затем свойства (в случае Chrome).

Например, в опере:

В Chrome 28:

и тогда в конце концов вы получите полезную часть:

в PhantomJS 1.9 еще хуже, вы получаете пронумерованные атрибуты, а затем только два именованных свойства: длина и cssText.

...
219: 'glyph-orientation-horizontal',
220: 'glyph-orientation-vertical',
221: '-webkit-svg-shadow',
222: 'vector-effect',
length: 223,
cssText: 'background-attachment: scroll; background-clip: border-box; background-color: rgba(0, 0, 0, 0); background-image: none; background-o...

2 ответа

Объект, возвращаемый во всех случаях, должен быть CSSStyleDeclaration экземпляр ( https://developer.mozilla.org/en-US/docs/Web/API/CSSStyleDeclaration).

Предполагается, что объект имеет только индексированные значения числа и length (делая его похожим на массив) и cssText,

Реализация Chrome добавляет нестандартные именованные атрибуты. Если вы хотите простой объект из пары свойство / значение, вы можете использовать getPropertyValue Метод по экземпляру. например (и большая часть этого кода взята из примера на MDN)

function simpleStyles(node) {
  var style = window.getComputedStyle(node);
  var styleMap = {};
  for (var i = 0; i < style.length; i++) {
    var prop = style[i]; //the numbered props
    var value = style.getPropertyValue(prop); //access the value;
    styleMap[prop] = value;
  }
  return styleMap;
}

//or fancier

function simpleStyles(node) {
  return Array.prototype.reduce.call(window.getComputedStyle(node), function(map, prop, _, style) {
    map[prop] = style.getPropertyValue(prop);
    return map;
  }, {});
}

getComputedStyle в Chrome перечисляет имена свойств. Некоторые свойства CSS имеют псевдонимы, поэтому доступ к псевдониму через массив или хэш в одной и той же структуре обеспечивает лучшее из обоих миров.

использование JSON.parse а также JSON.stringify чтобы нормализовать значения в разных браузерах:

    var foo = getComputedStyle(document.body);
    
    console.log(JSON.parse(JSON.stringify(foo), function(key, value){ if (/[0-9]+/.test(key)) return undefined; else return value; }) )

Рекомендации

Другие вопросы по тегам