我有这样的东西:
const someCSS = `
.foo {
padding: 20px;
background-color: #ddf;
width: 100px;
}
.bar {
height: 100px;
}
.foo {
padding-top: 30px; /* this overrides the previous one */
}
`;
我可以将此添加到 DOM 中,并使用这样的每个规则(jsFiddle)取回所有选择器:
const style = document.createElement('style');
style.innerHTML = someCSS;
document.head.append(style);
const styleSheet = Array.from(document.styleSheets).find(ss => ss.ownerNode == style);
const rules = Array.from(styleSheet.rules).map(rule => rule.cssText);
function styleToObject(rules, mergeWith = {}) {
return [...rules].reduce(
(obj, rule) => (obj[rule] = rules[rule], obj), mergeWith
);
}
const styleObject = Array.from(styleSheet.rules).reduce(
(obj, rule) => (obj[rule.selectorText] = styleToObject(rule.style, obj[rule.selectorText]), obj), {}
);
document.querySelector('pre').appendChild(
document.createTextNode(JSON.stringify(styleObject, null, '\t'))
);
得到这样的东西:
{
".foo": {
"padding-top": "30px",
"padding-right": "20px",
"padding-bottom": "20px",
"padding-left": "20px",
"background-color": "rgb(221, 221, 255)",
"width": "100px"
},
".bar": {
"height": "100px"
}
}
有没有另一种方法可以让浏览器在不接触 DOM 的情况下执行此操作?我的意思是让浏览器解析 CSS 文本(没有正则表达式),但实际上没有在页面中设置任何样式。
我想将其添加到 iFrame,但在将其附加到 DOM 之前文档不可用...
最佳答案
简短的回答是否定的,你不能不改变 DOM。
如果您担心添加的元素会触发重绘或加载的样式以任何方式影响页面,您可以将“永不匹配”媒体规则添加到 <style>
-您创建的元素。
例如:
style.setAttribute('media', '(max-width: 0)');
编辑 正在研究利用此技巧/技巧/解决方案的示例,您可以找到它 here .直到现在才注意到问题的更新,这在机制上非常相似(尽管我的示例将在不太绿色的浏览器中工作(我知道这不是问题的一部分))。
我检查了一些我在尝试做类似事情时遇到的资源,最值得注意的是 MDN - CSSStylesheets非常彻底并指出:
A CSSStyleSheet object is created and inserted into the document's styleSheets list automatically by the browser, when a style sheet is loaded for a document. As the document.styleSheets list cannot be modified directly, there's no useful way to create a new CSSStyleSheet object manually (although Constructable Stylesheet Objects might get added to the Web APIs at some point). To create a new stylesheet, insert a or element into the document.
(强调我的。@Ouroborus 已经提到了 CSO)
我没有在各种浏览器上做过很多测试,但是我没有看到通过将(媒体查询)样式节点添加到 <head>
来重绘和/或重排。 ,不像添加 <iframe>
.
我很好奇这里是否有人知道依赖(跨)浏览器处理 CSS 而不会触及 DOM 的解决方案,因为我还没有找到它并最终构建了一个 Tokenizer/Lexer 来创建这样的解决方案一棵树)。
关于javascript - 使用浏览器解析 CSS 而无需触及 DOM/样式,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40708902/