我尝试将样式表添加到SVG元素,如下所示:
var theSvg = document.createElementNS("http://www.w3.org/2000/svg", "svg");
var theStyle = document.createElementNS("http://www.w3.org/2000/svg", "style");
theSvg.appendChild(theStyle);
console.log("theStyle.sheet=", theStyle.sheet); // undefined, try adding svg to DOM
document.body.appendChild(theSvg);
console.log("theStyle.sheet=", theStyle.sheet); // still undefined
我应该怎样做才能到达theStyle
中的工作表节点?
这里有一个小提琴:http://jsfiddle.net/XaV7D/2/
答案 0 :(得分:2)
正如@RobertLongson在评论中指出的那样,问题在于SVG specs define a svg:style
element interface,但它并没有实现the CSS OM interfaces associated with a stylesheet's owner element。
以下是一些解决方法(在等待SVG 2规范实现最新的CSS OM规范时):
使用(X)HTML样式元素。如果您的SVG代码在(X)HTML文档中内联,则可以使用HTML <style>
元素来设置SVG的样式。只需确保在默认命名空间中创建样式元素或在XHTML命名空间中显式创建它,以便获得HTMLStyleElement
的实例,而不是SVGStyleElement
。
将新创建的HTMLStyleElement添加到文档的头部,并为您创建CSS样式表对象:
var hs = document.createElement("style");
hs.type = "text/css";
document.head.insertBefore(hs, null);
hs.sheet.insertRule("circle{fill:red;}", 0);
(理论上) 使用xml-stylesheet processing instruction。如果您的SVG代码位于独立的SVG文件中,则可以使用XML处理指令链接外部样式表。处理指令节点提供对样式表对象的访问。
但是,与<style>
元素(可以为空)不同,处理指令节点必须链接到文件,否则浏览器将永远不会初始化样式表对象。我试图通过将外部文件定义为正确MIME类型的空数据URI来解决这个问题。 从控制台运行时,通常(但不一致)在FF / Chrome中运行,但不是从嵌入式脚本运行。在Chrome中,sheet
属性始终为null,与Chrome相同处理跨域样式表; Firefox提供了明确的安全错误。我认为它在IE中根本不起作用,它不像非图像数据URI文件。
var xs = document.createProcessingInstruction(
"xml-stylesheet",
"href='data:text/css,' type='text/css'");
document.insertBefore(xs, document.rootElement);
xs.sheet.insertRule("circle{fill:blue;}", 0);
您并不清楚为什么您试图动态创建样式表。如果目的是实际链接到同域服务器上的有效样式表,那么安全问题就不是问题;问题是数据URI被视为跨源。
使用svg:style
元素,然后使用document.styleSheets
访问样式表对象(从评论到其他答案,似乎这就是您已经在做的事情)。遍历所有样式表,直到找到将样式元素作为所有者节点的样式表:
var ss = document.createElementNS("http://www.w3.org/2000/svg", "style");
svgElement.appendChild(ss);
var sheets = document.styleSheets,
sheet;
for(var i=0, length=sheets.length; i<length; i++){
sheet=sheets.item(i);
if (sheet.ownerNode == ss) break;
}
sheet.insertRule("circle{fill:green;}", 0);
无论您的SVG是否在独立文件中,这都应该有效。
答案 1 :(得分:0)
您可以在style
元素中使用svg
个节点。
来自MDN的示例:
<svg width="100%" height="100%" viewBox="0 0 100 100"
xmlns="http://www.w3.org/2000/svg">
<style>
/* <![CDATA[ */
circle {
fill: orange;
stroke: black;
stroke-width: 10px;
}
/* ]]> */
</style>
<circle cx="50" cy="50" r="40" />
</svg>
您可以像在HTML中一样追加它们。
var style = document.createElement('style');
style.setAttribute("type", "text/css");
var svg = document.getElementsByTagName("svg")[0];
svg.appendChild(style);
答案 2 :(得分:0)
IE11的SVGStyleElements中缺少“工作表”属性
根据AmeliaBR的回答,我做了一个polyfill:
if (!('sheet' in SVGStyleElement.prototype)) {
Object.defineProperty(SVGStyleElement.prototype, 'sheet', {
get:function(){
var all = document.styleSheets;
for (var i=0, sheet; sheet=all[i++];) {
if (sheet.ownerNode === this) return sheet;
}
}
});
}