提问人: 提问时间:1/6/2017 最后编辑:BoltClock 更新时间:1/8/2017 访问量:571
处理<?xml-stylesheet>类似于 <link rel=“stylesheet”>?
Handling <?xml-stylesheet> similar to <link rel="stylesheet">?
问:
在调查将CSS附加到处理指令的优缺点时,我遇到了一些问题。<?xml-stylesheet>
假设我们有一个简单的 XHTML 文档(它以 MIME 类型提供并在 Web 浏览器中查看):application/xhtml+xml
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>A sample XHTML document</title>
<script type="application/javascript" src="/script.js"></script>
</head>
<body>
<h1>A heading</h1>
</body>
</html>
然后我们有一个外部CSS文件(让它被命名并放在根目录中):style.css
h1 { color: red; }
首先,在 中,我动态地附加了一个元素:script.js
link
const link = document.createElement('link');
Object.entries({rel: 'stylesheet', type: 'text/css', href: '/style.css'})
.forEach(([name, value]) => link.setAttribute(name, value));
document.head.appendChild(link);
然后脚本会等待,直到样式表完成加载并通过属性到达它:sheet
link.addEventListener('load', function() {
const stylesheet = link.sheet;
});
在此之后,脚本可以操作此样式表,例如:
stylesheet.cssRules.item(0).style.color = 'green'; // modify an existing rule
stylesheet.insertRule('body { background: #ffc; }', 1); // insert a new rule
但是现在,我无法弄清楚如果样式表附加了处理指令,是否可以进行相同的操作:<?xml-stylesheet>
const pi = document.createProcessingInstruction('xml-stylesheet',
'href="/style.css" type="text/css"');
document.insertBefore(pi, document.documentElement);
首先,PI 似乎没有事件,因此脚本无法知道样式表何时准备就绪。其次,没有类似属性的东西,所以你不能调用来访问样式表。load
sheet
pi.sheet
有没有办法克服这些困难,并从脚本到与PI相关的样式表?<?xml-stylesheet>
答:
首先,PI 似乎没有加载事件,因此脚本无法知道何时 样式表已准备就绪。
您可以使用它来检查请求和加载的资源。迭代 的节点 ,检查 或 ,因为节点可以有 。从性能条目中获取属性。解析 URL 的过滤节点,检查 value 是否等于性能条目,然后检查 value 是否等于解析的 URL,以及解析的 URL 是否等于性能条目属性值。如果 ,则迭代 或 加载到节点。PerformanceObserver
document
.nodeType
7
.nodeType
8
ProcessingInstruction
comment
.nodeType
"resource"
.nodeValue
href="URL"
"resource"
.styleSheet
.href
"resource"
true
.cssRules
.rules
styleSheet
ProcessingInstruction
window.onload = () => {
let resource;
const observer = new PerformanceObserver((list, obj) => {
for (let entry of list.getEntries()) {
for (let [key, prop] of Object.entries(entry.toJSON())) {
if (key === "name") {
resource = prop;
var nodes = document.childNodes;
_nodes: for (let node of nodes) {
if (node.nodeType === 7 || node.nodeType === 8
&& node.nodeValue === pi.nodeValue) {
let url = node.baseURI
+ node.nodeValue.match(/[^href="][a-z0-9/.]+/i)[0];
if (url === resource) {
observer.disconnect();
// use `setTimeout` here for
// low RAM, busy CPU, many processes running
let stylesheets = node.rootNode.styleSheets;
for (let xmlstyle of stylesheets) {
if (xmlstyle.href === url && url === resource) {
let rules = (xmlstyle["cssRules"] || xmlstyle["rules"]);
for (let rule of rules) {
// do stuff
console.log(rule, rule.cssText, rule.style, xmlstyle);
break _nodes;
}
}
}
}
}
}
}
}
}
});
observer.observe({
entryTypes: ["resource"]
});
const pi = document.createProcessingInstruction('xml-stylesheet',
'href="style.css" type="text/css"');
document.insertBefore(pi, document.documentElement);
}
PLNKR http://plnkr.co/edit/uXfSzu0dMDCOfZbsdA7n?p=preview
您还可以使用 ,来处理MutationObserver
setTimeout()
RAM低,CPU繁忙,运行许多进程
window.onload = function() {
let observer = new MutationObserver(function(mutations) {
console.log(mutations)
for (let mutation of mutations) {
for (let node of mutation.addedNodes) {
if (node.nodeName === "xml-stylesheet") {
let url = node.baseURI
+ node.nodeValue.match(/[^href="][a-z0-9/.]+/i)[0];
setTimeout(function() {
for (let style of document.styleSheets) {
if (style.href === url) {
observer.disconnect();
// do stuff
console.log(style)
}
}
// adjust `duration` to compensate for device
// low RAM, busy CPU, many processes running
}, 500)
}
}
}
});
observer.observe(document, {
childList: true
});
const pi = document.createProcessingInstruction('xml-stylesheet',
'href="style.css" type="text/css"');
document.insertBefore(pi, document.documentElement);
}
PLNKR http://plnkr.co/edit/AI4QZiBUx6f1Kmc5qNG9?p=preview
或者,使用或请求文件,创建元素并将其附加到,对响应文本做事,将元素集设置为调整后的文本。XMLHttpRequest()
fetch()
.css
<style>
document
.textContent
style
css
评论
PerformanceObserver
style.css
document.styleSheets
cssRules
document.styleSheets
document.styleSheets
document.styleSheets
document.styleSheets
setInterval
setTimeout()
PerformanceObserver
MutationObserver
duration
setTimeout
评论
<?xml-stylesheet>
StyleSheet
xhtml
document
xhtml
document
window.onload
<!xml-stylesheet>
window.onload