您好我正在制作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; }
结果:
注意:我尝试使用图像元素,但是没有使用样式表,即我有一个黑色矩形而不是蓝色矩形。
重要提示:当您想引用另一个SVG 和希望将引用的SVG作为正式文档结构的一部分时,您可以use AJAX到那样做。
答案 0 :(得分:9)
从SVG规范中定义您linked to:
CSS2选择器不能应用于(概念上)克隆的DOM树 因为它的内容不是正式文件结构的一部分。
这意味着1.svg中的选择器不适用于克隆的DOM树。
那么为什么不简单地从another.svg引用样式表呢?这应该适用于所有浏览器,同时适用于<use>
和<image>
。
另一种选择是在主svg文档(1.svg)中设置<use>
元素的样式,因为样式也从那里级联到克隆树。
答案 1 :(得分:8)
这回答了原始问题,但也试图从更广泛的角度回答在SVG中引用外部SVG文件的问题。
六年后, Chrome和Safari仍然不允许引用/加载外部SVG文件。
这就是为什么<use xlink:href="another.svg#rectangle" class="blue"/>
适用于Firefox,但不适用于WebKit浏览器。
如果项目可以负担得起,只需将所有SVG文件放在一个父HTML或SVG文件中即可。这样,它可以在所有三种浏览器中运行:
然而,它不是外在的,被授予!
要从缓存中受益并避免重复自己,我们希望将可重复的SVG内容保存在外部文件中。
将样式和定义保存在一个SVG文件中,将SVG几何体保存在其他文件中,然后通过JavaScript从后者加载前者。
定义我们希望能够使用的内容。 styles-and-defs.svg
:
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<style type="text/css" >
<![CDATA[
.blue { fill: blue; }
]]>
</style>
<defs>
<rect id="rectangle" class="blue" width="50" height="50" />
</defs>
</svg>
使用上面创建的几何体,并加载其定义。 parent.svg
:
<svg version="1.1"
baseProfile="full"
xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink"
xmlns:ev="http://www.w3.org/2001/xml-events"
width="420" height="120">
<use xlink:href="#rectangle" x="10" y="10" />
<script><![CDATA[
/** When the document is ready, this self-executing function will be run. **/
(function() {
var ajax = new XMLHttpRequest();
ajax.open("GET", "styles-and-defs.svg", true);
ajax.send();
/**
* Append the external SVG to this very SVG.
*
* Notice the use of an SVG selector on the document derived from the AJAX result.
* This is because the full document cannot be included directly into the SVG.
* Trying to include to do so would result in:
* `HierarchyRequestError: Node cannot be inserted at the specified point in the hierarchy` in Firefox;
* `Nodes of type '#document' may not be inserted inside nodes of type 'svg'.` in Chrome.
*/
ajax.onload = function(e) {
var parser = new DOMParser();
var ajaxdoc = parser.parseFromString( ajax.responseText, "image/svg+xml" );
document.getElementsByTagName('svg')[0].appendChild( ajaxdoc.getElementsByTagName('svg')[0] );
}
})(); /* END (anonymous function) */
]]></script>
</svg>
这回答了OP。
与纯SVG相同的基本方法:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>
Load external SVG (HTML)
</title>
<meta name="author" content="Fabien Snauwaert">
</head>
<body>
<svg version="1.1"
baseProfile="full"
xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink"
xmlns:ev="http://www.w3.org/2001/xml-events"
width="420" height="120">
<use xlink:href="#rectangle" x="10" y="10" />
</svg>
<script>
/** When the document is ready, this self-executing function will be run. **/
(function() {
var ajax = new XMLHttpRequest();
ajax.open("GET", "styles-and-defs.svg", true);
ajax.send();
/**
* Append the external SVG to this very SVG.
*
* Notice the use of an SVG selector on the document derived from the AJAX result.
* This is because the full cannot be included directly into the SVG.
* Trying to include to do so would result in:
* `HierarchyRequestError: Node cannot be inserted at the specified point in the hierarchy` in Firefox;
* `Nodes of type '#document' may not be inserted inside nodes of type 'svg'.` in Chrome.
*/
ajax.onload = function(e) {
var parser = new DOMParser();
var ajaxdoc = parser.parseFromString( ajax.responseText, "image/svg+xml" );
document.getElementsByTagName('body')[0].appendChild( ajaxdoc.getElementsByTagName('svg')[0] );
}
})(); /* END (anonymous function) */
</script>
</body>
</html>
你当然可以使用jQuery(或者为什么不是优秀的D3.js)来加载文件。
<defs>
。我相信这是一个关于拥有外部SVG的好处,你可以保持一切整洁有序。 (如果没有它,我们将两次显示内容。)style.css
并简单地将CSS放在了styles-and-defs文件中。inline
元素。要摆脱这个差距,只需在该SVG上设置style="display: block;"
。SVG很棒但是看起来支持得太少了,而它确实允许一些很棒的东西。我希望这可以帮助一些人。
在OS X 10.12.6上的测试OK:
答案 2 :(得分:3)
尝试这样做:
广场:
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="1000" height="1000">
<rect x="558.5" y="570" width="5" height="5" id="rectangle" />
</svg>
使用它:
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<?xml-stylesheet href="style.css" type="text/css"?>
<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" class="blue"/>
</svg>
答案 3 :(得分:0)
<svg>
元素没有xlink:href
属性,如果您需要包含外部图片,请使用<image>
元素。