简体   繁体   中英

How to determine all CSS styles that are applied directly to an element?

Is it possible to get all CSS styles that are applied to a given HTML element either in its styles property/attribute or via CSS selectors?

I'm looking for the computed styles, but only those styles that are set on the element, not all existing styles that can possibly be set for the element.

Here is an example of what DOESN'T work.

 let span = document.querySelector('span'); let compStyles = getComputedStyle(span); console.log('The desired result is: "color: blue; font-style: italic"' ); console.log('But instead we get: ', compStyles.cssText );
 div {color: red; font-weight: bold} span {color: blue}
 <div> Hello <span style="font-style: italic">world</span> </div>

getComputedStyle gives a huge list of unneeded stuff. I'm only looking for the styles that are being applied directly to the element.

For example, DevTools shows at the top...
(1) the effective styles applied to the element, and below that it shows...
(2) the styles inherited from the parent. Then on a different tab, it shows...
(3) all computed styles.

I'm looking for number (1) only.


Why I need this.

When you select text in a page and copy that text, Chrome puts in the clipboard HTML code that looks like this:

<span style="color: rgb(255, 0, 0); font-family: 'Times New Roman'; font-size: medium; font-style: normal; font-variant: normal; font-weight: bold; letter-spacing: normal; line-height: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: 1; word-spacing: 0px; display: inline !important;">
    Hello
</span>
<span style="color: blue; font-family: 'Times New Roman'; font-size: medium; font-variant: normal; font-weight: bold; letter-spacing: normal; line-height: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: 1; word-spacing: 0px; font-style: italic;">
    world
</span>

ie every element has all its needed styles inline in its style attribute. That way the HTML code can be pasted anywhere else and it will look the same.
What Chrome is doing is to make the HTML code independent of any style sheets that may exist in the source page.

This is what I'm trying to do. I want to take a section of the page and generate it's equivalent HTML code with all its necessary styles integrated in the HTML itself.

What I want to avoid, though, is that the resulting HTML ends up being ridiculously big.
If I just take the result of getComputedStyle for every element, the final HTML will be a gigantic string.

Chrome does a good job at embedding the "important" styles (those that matter), instead of embedding literally every possible style property on every HTML element.

In general it appears possible, however this does make it seem that it won't be possible in Chrome.

TL;DR: As of Chrome 64 you'll need to use a local development server to test functionality that depends on the CSS Object Model.

This snippet below is using this code, with some small changes for the case of the OP.

 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({ text. e.cssText.match(/\w\s{\s(?*.)}/)[1] }) } } if (elm.getAttribute('style')) { rules:push({ text. elm;getAttribute('style') }) } return rules. } var styleSheetList = document;styleSheets. let span = document;querySelector('span'); var rules = getAppliedCss(span). console.log(rules.map(r => r.text);join(''));
 div {color: red; font-weight: bold} span {color: blue}
 <div> Hello <span style="font-style: italic">world</span> </div>

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM