11

我正在尝试使用 JavaScript DOM API 的XMLSerializer将 SVG 元素转换为其代表标记。

这是用于创建元素并对其进行序列化的基本代码:

var el = document.createElementNS('http://www.w3.org/2000/svg', 'svg');
el.setAttribute('xmlns', 'http://www.w3.org/2000/svg');
el.setAttribute('xmlns:xlink', 'http://www.w3.org/1999/xlink');

var markup = (new XMLSerializer()).serializeToString(el);
console.log(markup);

在 Chrome、Firefox、Safari 和 Opera 中,它会产生我想要的东西:

<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"/>

但是在 Internet Explorer 9 到 IE11 中,我得到了这个:

<svg xmlns="http://www.w3.org/2000/svg" xmlns="http://www.w3.org/2000/svg" xml:NS1="" NS1:xmlns:xlink="http://www.w3.org/1999/xlink" />

IE的输出有两个问题:

  1. 有重复的xmlns属性。如果我省略了 JavaScript 的第二行,那么在 IE 中标记中只有一个xmlns属性,但在 Firefox、Chrome、Safari 和 Opera 中,缺少该属性。
  2. 它增加了xml:NS1="". 为什么是这样?然后作为属性NS1:的前缀。xmlns:xlink

我认为我正在以正确的方式创建属性。例如,在这里使用setAttribute代替setAttributeNS是正确的(更多信息),并且改变它似乎并不能解决问题。

任何见解表示赞赏。

编辑:一个相关问题讨论了 Chrome 序列化中导致省略命名空间的错误。与第一个问题部分相关(尽管所有其他浏览器的行为相同),但与第二个问题无关。

4

1 回答 1

15

好的,我想我已经解决了。从这篇文章跟踪到这个WebKit 错误报告和这个测试用例

如果我将脚本更改为此,那么它可以工作:

var el = document.createElementNS('http://www.w3.org/2000/svg', 'svg');
el.setAttributeNS('http://www.w3.org/2000/xmlns/', 'xmlns', 'http://www.w3.org/2000/svg');
el.setAttributeNS('http://www.w3.org/2000/xmlns/', 'xmlns:xlink', 'http://www.w3.org/1999/xlink');

var markup = (new XMLSerializer()).serializeToString(el);
console.log(markup);

啊命名空间。

但是,它在 Safari 6.05 和 PhantomJS 中仍然存在的旧版 WebKit 中失败(错误报告- 现已修复)。大概该修复程序已包含在最新的 Safari 更新中(我尚未检查)。

于 2013-10-26T18:25:27.863 回答