导入外部 SVG(使用 WebKit)

发布于 2024-10-25 04:45:14 字数 402 浏览 2 评论 0原文

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

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

这是已知错误在 Chrome/WebKit 中, 所以除了尝试找到一种解决方法之外,我对此无能为力。我考虑过使用 XMLHttpRequest 来获取外部文件并将其插入到 svg 元素中。这会引起任何问题吗?有更好的方法吗?

The following works in Firefox 4, but not Chrome 10:

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

This is a known bug in Chrome/WebKit, so there's nothing I can do about that except try to find a way to work around it. I thought about using an XMLHttpRequest to grab the external file and insert it into the svg element. Will that cause any problems? Are there better ways to do it?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

昔梦 2024-11-01 04:45:14

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

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

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

但是,这不适用于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

After you fetch the SVG document via XHR you will have a separate XML document in the xhr.responseXML property. Since you cannot legally move nodes from one document to another, you'll need to import the portion you want from one document into your target document before you can use it as part of that document.

The simplest way to do this is to use document.importNode():

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

However, this does not work for IE9. To work around that bug, you can alternatively use this function to recursively recreate a node hierarchy in the document of choice:

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;
}

You can see an example of using XHR to fetch an SVG document and both techniques of importing the node on my website: http://phrogz.net/SVG/fetch_fragment.svg

行雁书 2024-11-01 04:45:14

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

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

我希望这有帮助。

I've written a simple and lighweight polyfill for this: https://github.com/Keyamoon/svgxuse

It detects whether or not it needs to send an HTTP request. If the browser doesn't support external references by default, it sends a GET request to fetch and cache the SVG.

I hope this helps.

荭秂 2024-11-01 04:45:14

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

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

I do a lot of AJAX requests for SVG markup, where I insert the markup into the DOM. You can't just insert it as a fragment, as far as I know, you have to recursively walk the retrieved XML doc, and create the individual SVG elements.

So, you might be better off combining the files on the server, before you send them to the browser.

醉梦枕江山 2024-11-01 04:45:14

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

In case someone stumbles accross this page. Here is a simpler way to use an HTTP request object to fetch the svg file:

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

The trick is in the following line (either you use window.fetch or xmlHttpRequest or whatever):

            var div = document.createElement('div');
            div.innerHTML = body;
            while (div.children.length > 0) {
                document.head.appendChild(div.children[0]);
            }
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文