WebKit/Phantomjs why output of getComputedStyles is that way?

1.3k views Asked by At

on most browsers (e.g. Firefox, Opera) getting the computed Style for a element return a nice object of type CSSStyleDeclaration. On Chrome 28 and PhantomJS 1.9 I get an object that starts with numbered keys listing all the CSS properties, and then the properties (in case of Chrome).

For example, in opera: enter image description here

In Chrome 28: enter image description here

and then eventually you get to the useful part: enter image description here

in PhantomJS 1.9 it's even worse, you get the numbered attributes, and then only two named properties: lenght and 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

There are 2 answers

0
thechriswalker On

The object returned in all cases should be a CSSStyleDeclaration instance (https://developer.mozilla.org/en-US/docs/Web/API/CSSStyleDeclaration).

The object is only supposed to have the number indexed values and a length (making it array-like) and cssText.

The Chrome implementation adds the non-standard named attributes. If you want an simple object of the property/value pairs, you can used the getPropertyValue method on the instance. e.g (and most of this code is from the example on 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;
  }, {});
}
0
Paul Sweatte On

getComputedStyle in Chrome enumerates property names. Some CSS properties have aliases, so accessing the alias through either an array or hash within the same structure provides the best of both worlds.

Use JSON.parse and JSON.stringify to normalize the values across browsers:

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

References