您好,我正在处理一个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; }
结果:
注意:我尝试过使用image元素,但在样式表中不起作用,即我得到了一个黑色的矩形,而不是蓝色的矩形。
重要提示:当您想要引用另一个SVG并且想要将引用的SVG作为正式文档结构的一部分时,您可以使用use AJAX来实现。
发布于 2018-05-03 18:42:00
这回答了最初的问题,但也试图从更广泛的角度回答在SVG中引用外部SVG文件的问题。
缺少SVG支持
六年后,SVG和Safari仍然不允许引用/加载外部文件。
这就是为什么<use xlink:href="another.svg#rectangle" class="blue"/>
可以在火狐中工作,而不能在WebKit浏览器中工作。
所有内容都在一个文件中
如果项目负担得起,只需将所有SVG文件放在一个父HTML或SVG文件中。这样,它将在所有三个浏览器中工作:
但话说回来,它并不是真正的外部,承认吧!
为了从缓存中获益并避免重复,我们希望将可重复的内容保存在外部文件中。
解决方法:通过JavaScript插入外部SVG文件
将样式和定义保存在一个SVG文件中,将SVG几何图形保存在其他文件中,然后简单地通过JavaScript从后者加载前者。
纯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>
这就回答了这个问题。
在HTML中
与纯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放在样式和定义文件中。inline
元素。要消除这种差距,只需在该SVG.上设置style="display: block;"
SVG很棒,但可能看起来支持得太少,而它确实允许一些很棒的事情。我希望这能对一些人有所帮助。
在OS X 10.12.6上测试正常:
59.0.2
发布于 2011-08-30 02:13:23
根据您linked to的SVG规范中的定义:
CSS2选择器不能应用于(概念上)克隆的DOM树,因为它的内容不是正式文档结构的一部分。
这意味着1.svg中的选择器不适用于克隆的DOM树。
那么为什么不直接引用another.svg中的样式表呢?这应该适用于所有浏览器,并且适用于<use>
和<image>
。
另一种选择是在主SVG文档(1.svg)中设置<use>
元素的样式,因为样式也从那里级联到克隆树。
发布于 2011-08-30 02:14:53
试着这样做:
正方形:
<?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>
https://stackoverflow.com/questions/7215009
复制相似问题