【问题标题】:Importing external SVG (with WebKit)导入外部 SVG(使用 WebKit)
【发布时间】:2011-07-21 16:14:33
【问题描述】:

以下适用于 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 元素中。这会导致任何问题吗?有更好的方法吗?

【问题讨论】:

标签: javascript google-chrome webkit svg


【解决方案1】:

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

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

【讨论】:

  • 看我的回答;除了作为 IE9 的解决方法之外,还有一种更简单的方法可以将节点导入目标文档:importNode
【解决方案2】:

通过 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

【讨论】:

  • 是的,我自己找到了 importNode() 技巧。但后来我发现 Android 版本的 WebKit 根本不支持 SVG,所以我决定完全忘记 SVG,只在这个项目中使用常规的位图图像。
  • (编辑:添加链接)这很好。感谢 Phrogz 对 SVG 的贡献。在构建my project 时,您的labs 不时帮助我。而且,哇,我刚刚学会了something new
【解决方案3】:

我为此编写了一个简单且轻量级的 polyfill:https://github.com/Keyamoon/svgxuse

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

我希望这会有所帮助。

【讨论】:

    【解决方案4】:

    以防有人偶然发现此页面。这是使用 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]);
                }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-08-13
      • 1970-01-01
      • 1970-01-01
      • 2021-07-23
      • 1970-01-01
      • 2012-03-23
      相关资源
      最近更新 更多