如何在SVG中正确引用外部SVG文件?
你好,我正在制作一个 SVG/JS 地图,它由许多小的 SVG 图形(城市区域)组成。我将每个图形放入一个自己的文件中,以便我的主 SVG 文件仍然可维护且不会臃肿。
如何正确从另一个 SVG 引用外部 SVG 文件?
预期结果:在浏览器中打开 1.svg 并看到一个蓝色矩形。 它应该如何工作: w3c: use element
这就是我的尝试过: 1.svg:
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<?xml-stylesheet href="style.css" type="text/css"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.0//EN" "http://www.w3.org/TR/2001/REC-SVG- 20010904/DTD/svg10.dtd">
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="1000" height="1000">
<use xlink:href="another.svg#rectangle"/>
</svg>
another.svg:
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.0//EN" "http://www.w3.org/TR/2001/REC-SVG- 20010904/DTD/svg10.dtd">
<svg id="rectangle" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="1000" height="1000">
<rect class="blue" x="558.5" y="570" width="5" height="5" />
</svg>
style.css
.blue { fill: blue; }
结果:
- Firefox:一个蓝色矩形(正是我想要的)
- Chrome:无
- Opera:黑色矩形
注意:我尝试过与图像元素一起使用,但这不适用于样式表,即我得到一个黑色矩形而不是蓝色矩形。
重要提示:当您想要引用另一个 SVG 并且希望引用的 SVG 成为正式文档结构的一部分时,您可以使用 AJAX 来做到这一点。
Hello I am working on an SVG/JS map, which consists of many little SVG graphics (City districts). I put every graphic into an own file so that my main SVG file will still be maintainable and not bloated.
How can I reference an external SVG file from another SVG correctly?
Expected result: Open 1.svg in a browser and see a blue rectangle.
How it should work: w3c: use element
So this is what I tried:
1.svg:
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<?xml-stylesheet href="style.css" type="text/css"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.0//EN" "http://www.w3.org/TR/2001/REC-SVG- 20010904/DTD/svg10.dtd">
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="1000" height="1000">
<use xlink:href="another.svg#rectangle"/>
</svg>
another.svg:
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.0//EN" "http://www.w3.org/TR/2001/REC-SVG- 20010904/DTD/svg10.dtd">
<svg id="rectangle" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="1000" height="1000">
<rect class="blue" x="558.5" y="570" width="5" height="5" />
</svg>
style.css
.blue { fill: blue; }
Result:
- Firefox: A blue rectangle (exactly what I wanted)
- Chrome: Nothing
- Opera: Black rectangle
Note: I tried it with the image element but that didn't work with the stylesheets i.e. I got a black rectangle not a blue one.
Important: When you want to reference another SVG and want to have the referenced SVG to be part of the formal document structure, you can use AJAX to do that.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
这回答了最初的问题,但也尝试从更广泛的角度回答在 SVG 中引用外部 SVG 文件的问题。
缺乏 SVG 支持
六年后,Chrome 和 Safari 仍然不允许引用/加载外部 SVG 文件。
这就是为什么
在 Firefox 中有效,但在 WebKit 浏览器中无效。
全部包含在一个文件中
如果项目可以负担得起,只需将所有 SVG 文件放入一个父 HTML 或 SVG 文件中即可。这样,它就可以在所有三种浏览器中运行:
但是,它并不是真正的外部,理所当然!
为了受益于缓存并避免重复,我们希望将可重复的 SVG 内容保留在外部文件中。
解决方法:通过 JavaScript 插入外部 SVG 文件
将样式和定义保留在一个 SVG 文件中,将 SVG 几何图形保存在其他文件中,只需通过 JavaScript 从后者加载前者即可。
在纯 SVG 和纯 JavaScript 中
定义我们希望能够使用的内容。
styles-and-defs.svg
:使用上面创建的几何图形,并加载其定义。
parent.svg
:这回答了OP。
在 HTML 中
与纯 SVG 中的基本方法相同:
您当然可以使用 jQuery(或者为什么不使用优秀的 D3.js)来加载文件。
备注 请
style.css
并简单地将 CSS 放在 styles-and-defs 文件中。style="display: block;"
即可。SVG 很棒,但似乎支持太少,尽管它确实可以实现一些很棒的功能。我希望这对一些人有帮助。
在 OS X 10.12.6 上测试正常:
This answers the original question, but attempts to answer the matter of referencing external SVG files in SVG in broader terms, too.
Lack of SVG support
Six years later, Chrome and Safari still do not allow for the referencing/loading of external SVG files.
This is why
<use xlink:href="another.svg#rectangle" class="blue"/>
works in Firefox, but not in WebKit browsers.All in one file
If the project can afford it, simply put all of the SVG files in one parent HTML or SVG file. This way, it'll work in all three browsers:
But then, it's not really external, granted!
To benefit from caching and avoid repeating oneself, we'd like to keep repeatable SVG content in an external file.
Work around: insert the external SVG file via JavaScript
Keep the styles and definitions in one SVG file, keep the SVG geometry in some other file, and simply load the former from the latter via JavaScript.
In pure SVG and pure JavaScript
Define what we'd like to be able to use.
styles-and-defs.svg
:Use the geometry created above, and load its definition.
parent.svg
:This answers the OP.
In HTML
Same basic approach as in pure SVG:
You could of course use jQuery (or why not the excellent D3.js) to load the file instead.
Remarks
<defs>
. I believe this is the nice thing about having an external SVG, you can keep everything neat and organized. (And without it, we'd be displaying the content twice.)style.css
and simply put the CSS inside of the styles-and-defs file.inline
element. To get rid of this gap, simply setstyle="display: block;"
on that SVG.SVG is great but can appear to be too little supported, while it does allow for some great things. I hope this helps some folks out there.
Tested OK on OS X 10.12.6 in:
根据您链接到的 SVG 规范中的定义:
这意味着 1.svg 中的选择器不适用于克隆的 DOM 树。
那么为什么不直接引用 another.svg 中的样式表呢?这应该适用于所有浏览器,并且适用于
和
。
另一种选择是在主 svg 文档 (1.svg) 中设置
元素的样式,因为样式也会从那里向下级联到克隆树。
From the definition in the SVG spec that you linked to:
That means that your selector in 1.svg doesn't apply to the cloned DOM tree.
So why not simply reference the stylesheet from another.svg instead? That should work in all browsers, and with both
<use>
and<image>
.Another option is to style the
<use>
element in the main svg document (1.svg), since style is cascaded down to the cloned tree from there too.尝试这样做:
正方形:
使用它:
Try to do it this way:
The square:
Use it:
如果您想引用整个 SVG 文件,SVG 2 (在浏览器中实现时)将允许引用另一个 SVG 文件,而无需任何 片段标识符:
之前:
之后(无需在
svg
上定义id="..."
):SVG 2 似乎正在主要浏览器中进行开发(请参阅此 Chrome 功能,特别是此 Chromium 问题:问题 366545:[SVG2] 允许引用整个文件)。
If you want to reference a whole SVG file, SVG 2 (when implemented in browsers) will allow to reference another SVG file without any fragment identifier:
Before:
After (there will be no need to define
id="..."
on thesvg
):SVG 2 seems to be in the process of development in major browsers (see this Chrome feature and specifically this Chromium issue: Issue 366545: [SVG2] Allow to reference entire files).
元素没有
xlink:href
属性,如果您需要包含外部图像,请使用元素。
<svg>
element doesn't havexlink:href
attribute, if you need to include an external image use the<image>
element.