I'm trying to get the current runtime style of an element and filter out properties that have default values. For example, with markup like this:
<style>
.foo { background: red }
span { font-size:30px }
</style>
<div style="color: blue">
<span id="bar" class="foo">hello</span>
</div>
I'd like the result to be:
background-color: red;
color: blue;
font-size: 30px;
I tried window.getComputedStyle
, but it returns a lot of stuff and I'm unsure how to filter out defaults. Any pointers will be appreciated.
there you go, i did this by adding a new dummy DOM element, to know which styles are default for any element.
/**
* IE does not have `getComputedStyle`
*/
window.getComputedStyle = window.getComputedStyle || function( element ) {
return element.currentStyle;
}
/**
* get computed style for an element, excluding any default styles
*
* @param {DOM} element
* @return {object} difference
*/
function getStylesWithoutDefaults( element ) {
// creating an empty dummy object to compare with
var dummy = document.createElement( 'element-' + ( new Date().getTime() ) );
document.body.appendChild( dummy );
// getting computed styles for both elements
var defaultStyles = getComputedStyle( dummy );
var elementStyles = getComputedStyle( element );
// calculating the difference
var diff = {};
for( var key in elementStyles ) {
if(elementStyles.hasOwnProperty(key)
&& defaultStyles[ key ] !== elementStyles[ key ] )
{
diff[ key ] = elementStyles[ key ];
}
}
// clear dom
dummy.remove();
return diff;
}
/**
* usage
*/
console.log( getStylesWithoutDefaults( document.getElementById( 'bar' ) ) );
Notes:
demo - console should be opened
Here's a more robust solution to this, using an iframe
. This solution is inefficient for more than one element at a time, in which case you'll want to use a fragment to batch element insertion and pass in an array of tag names.
var getDefaultStyling = function(tagName){
if(!tagName) tagName = "dummy-tag-name";
// Create dummy iframe
var iframe = document.createElement("iframe");
document.body.appendChild(iframe);
// Create element within the iframe's document
var iframeDocument = iframe.contentDocument;
var targetElement = iframeDocument.createElement(tagName);
iframeDocument.body.appendChild(targetElement);
// Grab styling (CSSStyleDeclaration is live, and all values become "" after element removal)
var styling = iframe.contentWindow.getComputedStyle(targetElement);
var clonedStyling = {};
for(var i = 0, len = styling.length; i < len; i++){
var property = styling[i];
clonedStyling[i] = property;
clonedStyling[property] = styling[property];
}
// Remove iframe
document.body.removeChild(iframe);
// Return cloned styling
return clonedStyling;
};
var getUniqueUserStyling = function(element){
var allStyling = window.getComputedStyle(element);
var defaultStyling = getDefaultStyling(element.tagName);
var userStyling = {};
for(var i = 0, len = allStyling.length; i < len; i++){
var property = allStyling[i];
var value = allStyling[property];
var defaultValue = defaultStyling[property];
if(value != defaultValue){
userStyling[property] = value;
}
}
return userStyling;
};
Usage: getUniqueUserStyling(myElement)
.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With