如何为SVG元素创建样式表? [英] How do I create a style sheet for an SVG element?

查看:132
本文介绍了如何为SVG元素创建样式表?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我尝试向SVG元素添加样式表,如下所示:

I tried to add a style sheet to an SVG element, like this:

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/

推荐答案

As @ RobertLongson在评论中指出,问题是 SVG规范定义了一个 svg:style 元素界面,但它不实现与样式表所有者元素相关联的CSS OM界面

As @RobertLongson points out in the comments, the problem is that the SVG specs define a svg:style element interface, but it doesn't implement the CSS OM interfaces associated with a stylesheet's owner element.

这里有一些解决方法等待SVG 2规范实现最新的CSS OM规范):

Here are a couple work-around approaches (while waiting for the SVG 2 specs to implement the latest CSS OM specs):


  1. 使用(X)HTML样式元素。如果您的SVG代码在(X)HTML文档内部是内联的,则HTML < style> 元素可用于对SVG进行样式化。只需确保您在默认命名空间中创建样式元素,或者在XHTML命名空间中显式创建它,以便获得 HTMLStyleElement ,而不是 SVGStyleElement

  1. Use an (X)HTML style element. If your SVG code is inline within an (X)HTML document, then the HTML <style> element can be used to style the SVG. Just make sure that you either create the style element in the default namespace or explicitly create it in the XHTML namespace, so that you get an instance of HTMLStyleElement, not SVGStyleElement.

将新创建的HTMLStyleElement添加到文档的头部,并为您创建CSS样式表对象: p>

Add the newly-created HTMLStyleElement to the head of your document, and the CSS stylesheet object will be created for you:

var hs = document.createElement("style");
hs.type = "text/css";
document.head.insertBefore(hs, null);
hs.sheet.insertRule("circle{fill:red;}", 0); 

这个答案详细介绍了HTML中动态创建样式表,包括一个工作示例。

(理论上) em> 使用 xml样式表处理说明。如果您的SVG代码在独立的SVG文件中,则可以使用XML处理指令来链接外部样式表。处理指令节点提供对样式表对象的访问。

(Theoretically) Use an xml-stylesheet processing instruction. If your SVG code is in a stand-alone SVG file, then you can use XML processing instructions to link external stylesheets. The processing instruction node provides access to the stylesheet object.

然而,与< style> 元素(可以为空)不同,处理指令节点必须链接到文件,否则浏览器将永远不会初始化样式表对象。我试图通过将外部文件定义为正确MIME类型的空数据URI来解决这个问题。 通常情况下,但不一致,在从控制台运行但不是嵌入式脚本的FF / Chrome中起作用。在Chrome中,属性始终为空,Chrome与跨网域样式表相同; Firefox提供了明确的安全错误。我认为它不会在IE中运行,它不喜欢非图像数据URI文件。

However, unlike a <style> element, which can be empty, the processing instruction node must link to a file, or the browser will never initialize the stylesheet object. I tried to get around that by defining the external file as an empty data URI of the correct MIME type. It usually, but not consistently, works in FF/Chrome when run from the console, but not from an embedded script. In Chrome, the sheet property is always null, the same way Chrome treats cross-domain stylesheets; Firefox gives an explicit security error. I assume it won't work at all in IE, which doesn't like non-image data URI files.

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被视为交叉原点。

You weren't clear about why you were trying to dynamically create a style sheet. If the intent is to actually link to a valid stylesheet on a same-domain server, then the security problems wouldn't be an issue; the problem is that data URIs are treated as cross-origin.

使用 svg:style 元素,但是然后使用 document.styleSheets (从注释到另一个答案,这似乎是您已经在做的)访问样式表对象。循环遍历所有样式表,直到找到具有您的样式元素的所有者节点为止:

Use a svg:style element, but then access the stylesheet object using document.styleSheets (from the comments to the other answer, it seems this is what you're already doing). Cycle through all the stylesheets until you find the one that has your style element as the owner node:

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是否在独立文件中,都应该可以工作。 >

This should work regardless of whether or not your SVG is in a stand-alone file.

这篇关于如何为SVG元素创建样式表?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆