0

考虑以下 SVG 块:

<defs>
  <radialGradient id="gradient" cx="50%" cy="50%" r="50%" fx="50%" fy="50%">
    <stop offset="0%" style="stop-color:#568f82;stop-opacity:1" />
    <stop offset="100%" style="stop-color:#568f82;stop-opacity:0" />
  </radialGradient>
</defs>

创建这些元素的相应 JavaScript 是:

var defs = document.createElementNS('http://www.w3.org/2000/svg', 'defs');
var radialGradient = document.createElementNS('http://www.w3.org/2000/svg', 'marker');
radialGradient.id = 'gradient';
radialGradient.setAttribute('cx', '50%');
radialGradient.setAttribute('cy', '50%');
radialGradient.setAttribute('fx', '50%');
radialGradient.setAttribute('fy', '50%');
radialGradient.setAttribute('r', '50%');
var stop1 = document.createElementNS('http://www.w3.org/2000/svg', 'path');
stop1.setAttribute('offset', '0%');
stop1.setAttribute('style', 'stop-color:#568f82;stop-opacity:1');
radialGradient.appendChild(stop1);
var stop2 = document.createElementNS('http://www.w3.org/2000/svg', 'path');
stop2.setAttribute('offset', '100%');
stop2.setAttribute('style', 'stop-color:#568f82;stop-opacity:0');
radialGradient.appendChild(stop2);
defs.appendChild(radialGradient);
this.svgElement.appendChild(defs);

有没有办法在 JavaScript 中使用内联 XML 标记?我尝试了类似以下的方法,但没有任何运气:

var defs = document.createElementNS('http://www.w3.org/2000/svg', 'defs');
defs.innerHTML = 
    '<radialGradient id="gradient" cx="50%" cy="50%" r="50%" fx="50%" fy="50%">' +
    '    <stop offset="0%" style="stop-color:#568f82;stop-opacity:1" />' +
    '    <stop offset="100%" style="stop-color:#568f82;stop-opacity:0" />' +
    '</radialGradient>';

似乎这innerHTML不是 的属性SVGElement

4

3 回答 3

2
var parser = new DOMParser();
var doc = parser.parseFromString(stringContainingXMLSource, "image/svg+xml");

请注意,父节点需要有一个明确的命名空间,以便正确解析,即字符串需要如下所示:

var stringContainingXMLSource = '<radialGradient xmlns="http://www.w3.org/2000/svg" id="gradient" ...

然后你可以做

defs.appendChild(document.importNode(doc.documentElement));

一些 UA 还允许 doc.rootElement 而不是 doc.documentElement 但显然不是全部。

于 2013-10-14T12:58:14.167 回答
1

没有直接的标记属性,但您可以使用它DOMParser.parseFromString()来将一些 XML 解析为新的 SVG 文档并importNode跨越它。或者,您可以使用innerHTML设置容器 HTML 元素的内容并将 SVG 节点从结果中拉出。

但是 string-slinging 有点麻烦——只要你想引入可变内容或属性值,很容易在不记住正确转义的情况下进行字符串连接,从而导致跨站点脚本问题。能够将所有内容保存在对象和属性的世界中而不是编码标记中,这很好。

诚然,超级详细的 DOM API 并不容易,但您可以编写快捷函数来为您调用 DOM 方法,允许您编写如下内容:

xml(SVG, 'defs', {}, [
    xml(SVG, 'radialGradient', {id: 'gradient', cx: '50%', cy: '50%', fx: '50%', fy: '50%' r: '50%'}, [
        xml(SVG, 'path', {offset:   '0%', 'stop-color': '#568f82', 'stop-opacity': 1}),
        xml(SVG, 'path', {offset: '100%', 'stop-color': '#568f82', 'stop-opacity': 0})
    ])
])

这更容易应对。

于 2013-10-14T13:15:05.453 回答
0

如果您想要更简洁的语法并且愿意使用库,请考虑尝试Raphaëlsvg.js。

于 2013-10-14T13:57:59.133 回答