像大多数web开发人员一样,我偶尔喜欢查看网站的源代码,看看它们的标记是如何构建的。像Firebug和Chrome开发者工具这样的工具可以很容易地检查代码,但是如果我想复制一个特定的部分并在本地使用它,复制所有单独的元素和它们相关的CSS将是一件痛苦的事情。保存整个源代码并删除不相关的代码可能需要做同样多的工作。

这将是伟大的,如果我可以在Firebug中右键单击一个元素,并有一个“保存HTML+CSS+JS为这个元素”选项。这样的工具存在吗?是否有可能扩展Firebug或Chrome开发工具来添加此功能?


当前回答

Webkit浏览器(FireBug不确定)允许您轻松地复制元素的HTML,因此这是过程的一部分。

在复制一个元素的HTML之前运行这个命令(在javascript控制台中)会将给定父元素的所有计算样式以及所有子元素移动到内联样式属性中,然后该属性将作为HTML的一部分可用。

var el = document.querySelector("#someid");
var els = el.getElementsByTagName("*");

for(var i = -1, l = els.length; ++i < l;){

    els[i].setAttribute("style", window.getComputedStyle(els[i]).cssText);

}

这是一个完全的hack,你会有很多“垃圾”css属性,但至少应该让你开始。

其他回答

我已经改编了投票最多的答案作为一个可拖动的书签。

只需访问此页面并拖动“运行jQuery代码”按钮到书签栏。

不需要插件。这可以用ie 11本地开发工具非常简单地完成,只需点击一下,非常干净。选中一个元素,检查该元素,右键单击某个块,选择“Copy element with styles”。你可以在下面的图片中看到它。

它提供了非常干净的css代码,比如

.menu { 
    margin: 0;
}
.menu li {
    list-style: none;
}

http://clipboardjs.com在这方面做得很好。尽管你期望复制的版本和原版完全一样,这样你就可以用它来玩和学习,但这可能不现实。

活泼片段

我终于找到时间来创建这个工具。你可以从Github安装SnappySnippet。它允许从指定的(最后检查的)DOM节点轻松提取HTML+CSS。此外,您可以将代码直接发送到CodePen或JSFiddle。享受吧!

其他功能

清理HTML(删除不必要的属性,修复缩进) 优化CSS使其可读 完全可配置(所有过滤器都可以关闭) 使用::before和::after伪元素 多亏了Bootstrap和Flat-UI项目

Code

SnappySnippet是开源的,你可以在GitHub上找到它的代码。

实现

因为我在做这个的时候学到了很多东西,所以我决定分享一些我经历过的问题和我的解决方法,也许有人会觉得很有趣。

第一次尝试- getMatchedCSSRules()

首先,我尝试检索原始的CSS规则(来自网站上的CSS文件)。令人惊讶的是,多亏了window.getMatchedCSSRules(),这非常简单,然而,它并没有很好地工作。问题在于,我们只选取了在整个文档上下文中匹配的HTML和CSS选择器的一部分,而在HTML片段上下文中不再匹配。由于解析和修改选择器似乎不是一个好主意,我放弃了这个尝试。

第二次尝试- getComputedStyle()

然后,我从@CollectiveCognition建议的东西开始- getComputedStyle()。然而,我真的想把CSS和HTML分开,而不是内联所有的样式。

问题1 -从HTML中分离CSS

这里的解决方案不是很漂亮,但很直接。我已经为所选子树中的所有节点分配了ID,并使用该ID创建适当的CSS规则。

问题2 -删除具有默认值的属性

Assigning IDs to the nodes worked out nicely, however I found out that each of my CSS rules has ~300 properties making the whole CSS unreadable. Turns out that getComputedStyle() returns all possible CSS properties and values calculated for the given element. Some of them where empty, some had browser default values. To remove default values I had to get them from the browser first (and each tag has different default values). The solution was to compare the styles of the element coming from the website with the same element inserted into an empty <iframe>. The logic here was that there are no style sheets in an empty <iframe>, so each element I've appended there had only default browser styles. This way I was able to get rid of most of the properties that were insignificant.

问题3 -只保留简写属性

我发现的下一件事是不必要地打印出具有速记等效的属性(例如,有border: solid black 1px,然后border-color: black;, border-width: 1px itd.)。 为了解决这个问题,我简单地创建了一个属性列表,这些属性具有简写等价物,并从结果中过滤掉它们。

问题4 -删除前缀属性

The number of properties in each rule was significantly lower after the previous operation, but I've found that I sill had a lot of -webkit- prefixed properties that I've never hear of (-webkit-app-region? -webkit-text-emphasis-position?). I was wondering if I should keep any of these properties because some of them seemed useful (-webkit-transform-origin, -webkit-perspective-origin etc.). I haven't figured out how to verify this, though, and since I knew that most of the time these properties are just garbage, I decided to remove them all.

问题5 -组合相同的CSS规则

我发现的下一个问题是相同的CSS规则一遍又一遍地重复(例如,对于每个具有完全相同样式的<li>,在创建的CSS输出中都有相同的规则)。 这只是相互比较规则,并将具有完全相同属性和值的规则组合在一起的问题。因此,#LI_1{…} # LI_2{…我得到了#LI_1, #LI_2{…}。

问题6 -清理和修复HTML的缩进

Since I was happy with the result, I moved to HTML. It looked like a mess, mostly because the outerHTML property keeps it formatted exactly as it was returned from the server. The only thing HTML code taken from outerHTML needed was a simple code reformatting. Since it's something available in every IDE, I was sure that there is a JavaScript library that does exactly that. And it turns out that I was right (jquery-clean). What's more, I've got unnecessary attributes removal extra (style, data-ng-repeat etc.).

问题7 -过滤器破坏CSS

因为在某些情况下,上面提到的过滤器可能会破坏代码片段中的CSS,所以我将它们都设置为可选的。您可以从“设置”菜单中禁用它们。

jQuery.fn.extend({
getStyles: function() {
    var rulesUsed = [];
    var sheets = document.styleSheets;
    for (var c = 0; c < sheets.length; c++) {
        var rules = sheets[c].rules || sheets[c].cssRules;
        for (var r = 0; r < rules.length; r++) {
            var selectorText = rules[r].selectorText.toLowerCase().replace(":hover","");
            if (this.is(selectorText) || this.find(selectorText).length > 0) {
                rulesUsed.push(rules[r]);
            }
        }
    }
    var style = rulesUsed.map(function(cssRule) {
        return cssRule.selectorText.toLowerCase() + ' { ' + cssRule.style.cssText.toLowerCase() + ' }';
    }).join("\n");
    return style;
}
});

用法:$ (" # login_wrapper ") .getStyles ()