Это отвечает на исходный вопрос, но пытается ответить на вопрос ссылки на внешние SVG-файлы в SVG также в более широком смысле.
Отсутствие поддержки SVG
Шесть лет спустя Chrome и Safari по-прежнему не допускают ссылки / загрузки внешних файлов SVG .
Именно поэтому <use xlink:href="another.svg#rectangle" class="blue"/>
работает в Firefox, но не в браузерах WebKit.
Все в одном файле
Если проект может себе это позволить, просто поместите все файлы SVG в один родительский файл HTML или SVG. Таким образом, он будет работать во всех трех браузерах:
Но тогда, это не действительно внешнее, само собой разумеется!
Чтобы извлечь выгоду из кэширования и избежать повторения, мы хотели бы сохранить воспроизводимый SVG-контент во внешнем файле.
Обход: вставьте внешний файл SVG с помощью JavaScript
Храните стили и определения в одном файле 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 внутри файла styles-and-defs.
- Если в версии HTML вы наблюдаете разрыв между родительским SVG и границами окна, то это потому, что «невидимый» SVG (со стилями и определением), как и любой другой SVG, является элементом
inline
, Чтобы избавиться от этого пробела, просто установите style="display: block;"
на этом SVG.
- Скачать все примеры можно здесь .
SVG великолепен, но может показаться слишком мало поддерживаемым, хотя и допускает некоторые замечательные вещи. Я надеюсь, что это поможет некоторым людям там.
Проверено нормально на OS X 10.12.6 в:
- Firefox 59.0.2
- Chrome 66.0.3359.139
- Safari 11.0.1