简体   繁体   English

如何确定所有直接应用于元素的 CSS styles?

[英]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? 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.我正在寻找计算得到的 styles,但只有那些在元素上设置的 styles,而不是所有可能为元素设置的现有 styles。

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. getComputedStyle提供了大量不需要的东西。 I'm only looking for the styles that are being applied directly to the element.我只是在寻找直接应用于元素的 styles。

For example, DevTools shows at the top...例如,DevTools 显示在顶部...
(1) the effective styles applied to the element, and below that it shows... (1)有效的styles应用于元素,下面显示...
(2) the styles inherited from the parent. (2) styles 继承自父代。 Then on a different tab, it shows...然后在另一个选项卡上,它显示...
(3) all computed styles. (3) 所有计算的 styles。

I'm looking for number (1) only.我只寻找数字(1)。


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:当您在页面中使用 select 文本并复制该文本时,Chrome 会在剪贴板中放入如下所示的 HTML 代码:

<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.即每个元素在其style属性中都有其所有需要的 styles 内联。 That way the HTML code can be pasted anywhere else and it will look the same.这样,HTML 代码可以粘贴到其他任何地方,并且看起来相同。
What Chrome is doing is to make the HTML code independent of any style sheets that may exist in the source page. Chrome 正在做的是使 HTML 代码独立于源页面中可能存在的任何样式表。

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.我想截取页面的一部分并生成等效的 HTML 代码,其所有必要的 styles 都集成在 HTML 本身中。

What I want to avoid, though, is that the resulting HTML ends up being ridiculously big.不过,我想避免的是,生成的 HTML 最终变得非常大。
If I just take the result of getComputedStyle for every element, the final HTML will be a gigantic string.如果我只为每个元素getComputedStyle的结果,那么最终的 HTML 将是一个巨大的字符串。

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. Chrome 在嵌入“重要的”styles(那些重要的)方面做得很好,而不是在每个 HTML 元素上嵌入所有可能的样式属性。

In general it appears possible, however this does make it seem that it won't be possible in Chrome.一般来说,这似乎是可能的,但这确实使它看起来在 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. TL;DR:从 Chrome 64 开始,您需要使用本地开发服务器来测试依赖于 CSS Object Model 的功能。

This snippet below is using this code, with some small changes for the case of the OP.下面的这段代码使用了这段代码,对 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>

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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