2011-03-23 22 views
4

在Firefox 4以下的作品,而不是Chrome浏览器10:导入外部SVG(与WebKit的)

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

这是a known bug in Chrome/WebKit,所以没有什么我可以做的只是试图找到一种方法来解决它。我想过使用XMLHttpRequest来抓取外部文件并将其插入到svg元素中。会造成什么问题吗?有没有更好的方法来做到这一点?

+0

在迈克或@Progrog:可以编程方式测试这个'使用'功能没有浏览器嗅探? – 2011-10-07 22:43:39

+0

相关问题 - http://stackoverflow.com/questions/1811116/ie-support-for-dom-importnode – resnyanskiy 2012-03-26 03:13:38

回答

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。要解决这个bug,您也可以使用此功能选择的文件中递归地重新创建节点层次结构:

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

+0

是的,我自己找到了importNode()技巧。但后来我发现Android的WebKit版本根本不支持SVG,所以我决定完全忘记SVG,并为这个项目使用普通的位图图像。 – 2011-05-20 18:52:44

+0

(编辑:链接添加)这是非常好的。感谢Phrogz,感谢您对SVG的贡献。你的[实验室](http:// phrogz。net/svg /)在构建[我的项目](http://www.progettystudio.com)时不时帮助我。哇,我刚刚学到了[新东西](http://phrogz.net/svg/textRendering.svg) – 2011-07-16 16:57:03

0

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

因此,在将它们发送到浏览器之前,将服务器上的文件组合起来可能会更好。

+0

看到我的答案;除了作为IE9的解决方法之外,还有一种将节点导入目标文档的简单方法:['importNode'](https://developer.mozilla.org/en/DOM/document.importNode)。 – Phrogz 2011-05-20 17:44:09

0

我写了一个简单而lighweight填充工具为此:https://github.com/Keyamoon/svgxuse

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

我希望这会有所帮助。

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]); 
      } 
+0

哦,这里有一个window.fetch的polyfill - > https://github.com/github/取 – 2015-12-18 16:12:44