SVG standard allows to use and refer external SVG files.
I have a file circle.svg
that defines a circle object with id "the_circle".
From the main SVG file I am able to include this circle and animate it, using SVG linking.
I would also like to access the same circle object via javascript, how can I do this ?
What is the javascript equivalent of xlink:href="url(#the_image)#the_circle"
?
Using document.getElementById('the_image')
I can only access the SVGImageElement but not the objects defined inside the included SVG.
<?xml version="1.0" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg width="100%" height="100%" version="1.1"
xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" >
<image
id="the_image"
x="0" y="0" width="100%" height="100%"
xlink:href="circle.svg" />
<animateTransform
xlink:href="url(#the_image)#the_circle"
attributeName="transform" attributeType="XML"
type="translate"
from="0" to="25"
dur="1s" repeatCount="indefinite"
additive="replace" fill="freeze" />
</svg>
SVG images can be written directly into the HTML document using the <svg> </svg> tag. To do this, open the SVG image in VS code or your preferred IDE, copy the code, and paste it inside the <body> element in your HTML document. If you did everything correctly, your webpage should look exactly like the demo below.
The SVG DOM builds upon and is compatible with DOM Level 2. In particular: The SVG DOM requires complete support for DOM Level 2 Core [DOM2] Wherever appropriate, the SVG DOM is modeled after and maintains consistency with the Document Object Model HTML ([DOM1], chapter 2).
The Document Object Model (DOM) is an API for XML documents. It defines the logical structure of documents and the way a document is accessed and manipulated.
A SVG element is identified with tagname svg. The svg image has the attributes like width and height attributes. Let us investigate the html code of a svg element. To create a xpath for a svg element, we have the syntax as //*[local-name()='svg'].
It seems like the "right" way to do this would actually be to use an SVG "use" element, rather than an image. The reason for this is that the DOM interface of the SVG use element specifies a property "instanceRoot", which allows you to get the root of the "instance tree" corresponding to that use element: http://www.w3.org/TR/SVG/struct.html#InterfaceSVGUseElement
So, you would end up with a solution that looks something like the following: circle.svg:
<?xml version="1.0" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN"
"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg width="4in" height="4in" id="the_svg"
viewBox="0 0 4 4" version="1.1"
xmlns="http://www.w3.org/2000/svg">
<circle r="1" fill="blue" stroke="none" id="the_circle"/>
</svg>
Document which uses the svg root node of circle.svg:
<?xml version="1.0" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN"
"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg width="100%" height="100%" id="foo"
version="1.1"
xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink">
<use xlink:href="circle.svg#the_svg"/>
</svg>
Unfortunately, though, while Firefox supports use of the use element with external documents, there's currently a bug in Webkit which does not allow this: https://bugs.webkit.org/show_bug.cgi?id=12499
Also, Firefox does not seem to implement the instanceRoot property for use elements.
So, it seems you may need to work around the limitations of current SVG implementations. The way I would recommend doing this is to use XMLHttpRequest to download the document to which you would like to link, and import the DOM of the downloaded document into your host document's DOM. The following code implements this, and works in Firefox, Opera and Chromium:
<?xml version="1.0" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN"
"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg width="100%" height="100%" id="foo"
version="1.1"
xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink">
<script>
function fetchXML (url, callback) {
var xhr = new XMLHttpRequest();
xhr.open('GET', url, true);
xhr.onreadystatechange = function (evt) {
//Do not explicitly handle errors, those should be
//visible via console output in the browser.
if (xhr.readyState === 4) {
callback(xhr.responseXML);
}
};
xhr.send(null);
};
//fetch the document
fetchXML("http://localhost:8082/tmp/circle.svg",function(newSVGDoc){
//import it into the current DOM
var n = document.importNode(newSVGDoc.documentElement,true);
document.documentElement.appendChild(n);
var circle = document.getElementById("the_circle"); //now you have the circle
})
</script>
</svg>
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With