window.getComputedStyle() 方法在应用活动样式表并解决这些值可能包含的任何基本计算后给出元素的所有 CSS 属性的值。
下面的演示省略了对 pseudo-elements 的跟踪,但使用 window.getComputedStyle(element[, pseudoElt]); 时可能会硬塞住该功能,其中:
element
要为其获取计算样式的元素。
pseudoElt 可选
指定要匹配的伪元素的字符串。对于常规元素,必须省略(或为 null)。
用法
- 通过
<script> 或开发者控制台将代码添加到您正在处理的 HTML 文档中。
- 使用
setInitStyles() 设置或重置每个元素的样式状态,与调用differenceEngine() 时进行比较。
- 使用
differenceEngine() 获取上次调用setInitStyles() 和现在 时设置的样式之间的差异。
示例
此代码将受益于一些优化,并且改变口味即输出格式可能是不可取的。
sn-p 将按预期运行(在 Chrome 中测试),但由于大量数据记录到 console,我禁用了 sn-p 的 控制台(为了提高效率)所以您需要在浏览器中查看输出。
const compressedStyles = ( e ) => {
const ucs = window.getComputedStyle( e );
var s, cs = {};
for ( s in ucs ) {
if ( ucs.hasOwnProperty( s ) && /[^0-9]+/.test( s ) ) {
cs[ s.replace( /([A-Z])/g, "-$1" ).toLowerCase() ] = ucs[ s ];
}
}
return cs;
},
setElementStyles = ( e ) => {
e.stylesInit = compressedStyles( e );
e.stylesDiff = {}; // while we're here
},
allTheThings = () => {
var att = Array.from( document.body.querySelectorAll( "*:not( script )" ) );
att.unshift( document.body );
return att;
},
setInitStyles = () => {
allTheThings().forEach( setElementStyles );
},
differenceEngine = () => {
allTheThings().forEach( ( e ) => {
if ( e.stylesInit ) {
const cs = compressedStyles( e );
var s, css, ess;
for ( s in e.stylesInit ) {
ess = e.stylesInit[ s ].toString();
css = cs[ s ].toString();
if ( ess != css ) {
e.stylesDiff[ s ] = { "curr": css, "init": ess };
}
}
console.log( e, e.stylesDiff );
} else {
setElementStyles( e ); // set current styles on new elements
}
} );
};
console.info( "Setting the initial styles" );
setInitStyles();
console.info( "Changing the style of one of the elements" );
document.querySelector( "div" ).style.border = "2px solid red";
console.info( "What's the difference?" );
differenceEngine();
console.info( "Resetting the style of the element" );
document.querySelector( "div" ).removeAttribute( "style" );
console.info( "What's the difference?" );
differenceEngine();
console.info( "Changing the class of one of the elements" );
document.querySelector( "p" ).classList.add( "foo" );
console.info( "What's the difference?" );
console.warn( "Properties that inherit from color have also changed" );
differenceEngine();
console.info( "Resetting the class of the element" );
document.querySelector( "p" ).classList.remove( "foo" );
console.info( "What's the difference?" );
differenceEngine();
p.foo {
color: red;
}
<div>
<p>Foo</p>
<p>Bar</p>
<p>Baz</p>
</div>
出于对追逐的热爱,作为建议,而不是最终解决方案。
由于getComputedStyle() 正是这样做的,因此上述结果可能没有什么帮助。
将注意力转向实际的 DevTools,我们可以检查它们(当弹出并聚焦时)并在检查器上运行脚本。
这是向使用 Chrome 扩展扩展 DevTools 迈出的一步。
在思考构建过程时,我偶然发现了SnappySnippet;一个受 a Stack Overflow question 启发的 Chrome 扩展程序,据说(我没有使用它)可以轻松地从网页创建片段。
该扩展程序可能会提供可以有效回答您的问题的功能,但如果它没有(并且为了好玩),我已经开始研究可能成为另一个 Chrome 扩展程序的功能。
请注意,这个过程可能漫长、缓慢且毫无结果;如果在任何时候我创建了比下面的代码更有用的东西,我会回来更新这个答案。
我在此展示我的最新组合! \o/
document.querySelectorAll( ".styles-section" ).forEach( ( e ) => {
var output;
const selector = e.querySelector( ".selector" ).textContent,
properties = e.querySelector( ".style-properties" )
.shadowRoot.querySelectorAll( ".tree-outline > li" );
if ( properties ) {
output = selector + " {\n";
properties.forEach( ( p ) => {
const property = p.querySelector( ".webkit-css-property" ).textContent,
value = p.querySelector( ".value" ).textContent;
if ( p.classList.contains( "inactive" ) ) {
output += "\t/* " + property + ": " + value + "; */\n";
} else {
output += "\t" + property + ": " + value + ";\n";
}
} );
}
console.log( output + "}" );
} );
当在检查器上的检查器上运行此代码时(不是拼写错误),将为原始 HTML 的检查器中当前选定的元素输出样式窗格内容的漂亮副本。
嗯-混搭。
与其吐出一堆文本,不如对其进行相对简单的调整以吐出一个数据对象,就像我的第一个响应的代码中一样,可以与其他快照进行比较以获得差异。
而且,由于此代码是在检查器上运行,而不是在被操作的文档上运行,因此这是朝着我们可以通过 DevTools 扩展实现的目标迈出的坚实一步。
我将继续摆弄这个,并在我去的时候更新这个答案,但不要屏住呼吸。
手动解决方案(代替魔法)
虽然不是高科技,但有一种非常简单可靠的方法可以跟踪资源或<style>sheets 对element.style 和CSS 所做的更改:
正如您在上面的屏幕截图中所见,我们可以将 cmets 添加到我们更改或添加的任何属性的任何值中,显示以前的值是什么,或者该值是全新的。
当然,如果我们想删除任何东西,我们可以取消选中属性左侧的复选框,这样该值就会被保留。