导入外部SVG(使用WebKit)

时间:2011-03-23 21:28:38

标签: javascript google-chrome webkit svg

以下适用于Firefox 4,但不适用于Chrome 10:

<svg:svg version="1.1">
    <svg:use xlink:href="some_file.svg#layer1"/>
</svg:svg>

这是a known bug in Chrome/WebKit,所以除了试图找到一种解决方法之外,我无能为力。我考虑使用XMLHttpRequest来获取外部文件并将其插入svg元素。这会导致任何问题吗?有更好的方法吗?

4 个答案:

答案 0 :(得分:4)

通过XHR获取SVG文档后,xhr.responseXML属性中将有一个单独的XML文档。由于您无法合法地将节点从一个文档移动到另一个文档,因此您需要将所需的部分从一个文档导入到目标文档中,然后才能将其用作该文档的一部分。

最简单的方法是使用document.importNode()

var clone = document.importNode(nodeFromAnotherDoc,true);
// Now you can insert "clone" into your document

然而,this does not work for IE9。要解决该错误,您可以使用此函数以递归方式在所选文档中重新创建节点层次结构:

function cloneToDoc(node,doc){
  if (!doc) doc=document;
  var clone = doc.createElementNS(node.namespaceURI,node.nodeName);
  for (var i=0,len=node.attributes.length;i<len;++i){
    var a = node.attributes[i];
    clone.setAttributeNS(a.namespaceURI,a.nodeName,a.nodeValue);
  }
  for (var i=0,len=node.childNodes.length;i<len;++i){
    var c = node.childNodes[i];
    clone.insertBefore(
      c.nodeType==1 ? cloneToDoc(c,doc) : doc.createTextNode(c.nodeValue),
      null
    );
  }
  return clone;
}

您可以看到使用XHR获取SVG文档的示例以及在我的网站上导入节点的两种技术:http://phrogz.net/SVG/fetch_fragment.svg

答案 1 :(得分:0)

我做了很多关于SVG标记的AJAX请求,我将标记插入到DOM中。您不能只将其作为片段插入,据我所知,您必须递归遍历检索到的XML文档,并创建单独的SVG元素。

因此,在将文件发送到浏览器之前,最好合并服务器上的文件。

答案 2 :(得分:0)

我为此写了一个简单的轻量级填充物:https://github.com/Keyamoon/svgxuse

它检测是否需要发送HTTP请求。如果浏览器默认不支持外部引用,它会发送一个GET请求来获取和缓存SVG。

我希望这会有所帮助。

答案 3 :(得分:0)

如果有人在这个页面上绊倒了。以下是使用HTTP请求对象获取svg文件的更简单方法:

window
    .fetch('/assets/ciphers.svg')
    .then(
        function (response) {
            return response.text();
        }
    ).then(
        function (body) {
            var div = document.createElement('div');
            div.innerHTML = body;
            while (div.children.length > 0) {
                document.head.appendChild(div.children[0]);
            }
        }
    );

诀窍在以下行中(您使用window.fetch或xmlHttpRequest或其他):

            var div = document.createElement('div');
            div.innerHTML = body;
            while (div.children.length > 0) {
                document.head.appendChild(div.children[0]);
            }