How to get application style from an element, excluding default user agent styles

As in JavaScript, you retrieve the styles that were applied to the element, excluding the default user agent styles (only for inline + styles).

Basically, all the custom styles that you can see on the Computed tab of your favorite developer tool:

Custom Styles Displayed in the Edge Developer Tool

Borderless, please IE8 +, Edge, Chrome and Firefox.

I expect the answer to be the result of getComputedStyle minus getDefaultComputedStyle , but in a cross browser. Seeing that all the developer tools are able to do this, there must be a solution :)

+4
3

"StyleSheets".

var styleSheetList = document.styleSheets;

https://developer.mozilla.org/en-US/docs/Web/API/Document/styleSheets

, , .

, :

, CSS Javascript?

, , , .

style , :

var proto = Element.prototype;
var slice = Function.call.bind(Array.prototype.slice);
var matches = Function.call.bind(proto.matchesSelector || 
                proto.mozMatchesSelector || proto.webkitMatchesSelector ||
                proto.msMatchesSelector || proto.oMatchesSelector);

// Returns true if a DOM Element matches a cssRule
var elementMatchCSSRule = function(element, cssRule) {
  return matches(element, cssRule.selectorText);
};

// Returns true if a property is defined in a cssRule
var propertyInCSSRule = function(prop, cssRule) {
  return prop in cssRule.style && cssRule.style[prop] !== "";
};

// Here we get the cssRules across all the stylesheets in one array
var cssRules = slice(document.styleSheets).reduce(function(rules, styleSheet) {
  return rules.concat(slice(styleSheet.cssRules));
}, []);




var getAppliedCss = function(elm) {
	// get only the css rules that matches that element
	var elementRules = cssRules.filter(elementMatchCSSRule.bind(null, elm));
	var rules =[];
	if(elementRules.length) {
		for(i = 0; i < elementRules.length; i++) {
			var e = elementRules[i];
			rules.push({
				order:i,
				text:e.cssText
			})
		}		
	}
	
	if(elm.getAttribute('style')) {
		rules.push({
				order:elementRules.length,
				text:elm.getAttribute('style')
			})
	}
	return rules;
}







function showStyle(){
var styleSheetList = document.styleSheets;
// get a reference to an element, then...
var div1 = document.getElementById("div1");

var rules = getAppliedCss(div1);

var str = '';
for(i = 0; i < rules.length; i++) {
			var r = rules[i];
			str += '<br/>Style Order: ' + r.order + ' | Style Text: ' + r.text; 
		}		
		
	document.getElementById("p1").innerHTML = str;	

}
#div1 {
float:left;
width:100px;
}

div {
text-align:center;
}
<div id="div1" style="font-size:14px;">
	Lorem ipsum 
	</div>
<br/>
<br/>
<a href="javascript:;" onclick="showStyle()"> Show me the style. </a>
	<p id="p1"><p>
Hide result
+5

, , .

, .

  • (, div p) , .
  • - , . , iframe.
    , , - p, , .
  • .
  • .

, . Firefox Chrome, , - , , - , for...in for...of, . , , , , . , , , , color: white.

, , , getNonDefaultStyles, , , , . , , , div , , ( DOM ), .

, . - StackOverflow iframe . JSFiddle. Fiddle.

var textarea = document.getElementById("textarea"),
    paragraph = document.getElementById("paragraph");

/**
 * Computes applied styles, assuming no rules targeting a specific element.
 */
function getNonDefaultStyles(el) {
  var styles = {},
    computed = window.getComputedStyle(el),
    notTargetedContainer = document.createElement('div'),
    elVanilla = document.createElement(el.tagName);
  document.body.appendChild(notTargetedContainer);
  notTargetedContainer.appendChild(elVanilla);
  var vanilla = window.getComputedStyle(elVanilla);
  for (let key of computed) {
    if (vanilla[key] !== computed[key]) {
      styles[key] = computed[key];
    }
  }
  document.body.removeChild(notTargetedContainer);
  return styles;
}

var paragraphStyles = getNonDefaultStyles(paragraph);
for (let style in paragraphStyles) {
  textarea.value += style + ": " + paragraphStyles[style] + "\n";
}
#paragraph {
  background: red;
}

textarea {
  width: 300px;
  height: 400px;
}
<p id="paragraph" style="color: white">
  I am a DIV
</p>

<p>
  User styles:
</p>
<textarea id="textarea"></textarea>
Hide result
+3

I have used this feature in the past ...

function get_style(obj,nam) { //obj = HTML element, nam = style property
  var val = "";
  if(document.defaultView && document.defaultView.getComputedStyle) {
    nam = nam.replace(/[A-Z]/g,function(str) { //convert name into hypenated
      return "-"+str.toLowerCase();
    });
    val = document.defaultView.getComputedStyle(obj,"").getPropertyValue(nam); //get current style
  }
  else if(obj.currentStyle) {
    nam = nam.replace(/\-(\w)/g,function(str,p1) { //convert name into camel case
      return p1.toUpperCase();
    });
    val = obj.currentStyle[nam]; //get current style
  }
  return val;
}
Run codeHide result

It allows you to pass the style property to both hypenated ( background-color) and the camel case ( backgroundColor) and replaces it depending on the method that it uses.

This also applies to older browsers, even older IEs!

0
source

Source: https://habr.com/ru/post/1668742/


All Articles