Web developers use JavaScript to achieve many things in SVG, including animation, interaction, creating and modifying elements, but adding a script inside an SVG document comes with a few special caveats:
JavaScript can be added anywhere in an SVG document between the opening and closing
<svg>
tags. In general, a script should be placed at the end of the document to avoid blocking and allow the script complete access to the DOM.Most resources will tell you to set the script’s MIME type (i.e.
<script type="text/javascript">
or<script type="application/ecmascript">
). However, this isn’t necessary: JavaScript/ECMAScript is the default in browsers, and doesn’t need to be stated, even in the context of SVG.Similarly, most resources will tell you to wrap your JavaScript code in
<[CDATA[
when it is inside an SVG:<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 500 500"> <script>//<![CDATA[ …code… //]]> </script> </svg>
Because browsers will sometimes attempt to parse JavaScript as XML inside SVG, becoming terminally confused in the process, the commented CDATA “protects” the script from this interpretation. Modern browsers don’t necessarily need this protection, but it’s the safest approach.
You can reference external scripts, but must use
xlink:
to do so:<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"> <script xlink:href="external.js" /> </svg>
- SVG is XML, not HTML, so a few methods associated with the DOM, such as
innerHTML
, don’t work in SVG (although there are workarounds).
Otherwise, JavaScript works in much the same way as it would in an HTML document: you can reference ids, elements, etc, like normal. The only special consideration is creating and addressing case-sensitive namespaced elements, which I will address in a future article.
Potential Frustrations
The most common confusion when embedding JavaScript in SVG is the fact that SVG documents added to the page as images will have their JavaScript ignored. That is:
<img src="getfunky.svg" alt="" >
…will have any JavaScript inside the SVG ignored (SMIL won’t be ignored in some browsers, but SMIL is scheduled to deprecated in any case). There are two possible ways around this:
Embed the SVG directly in the page, rather than referencing it as an image:
<html lang="en"> … <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 500 500"> <script>//<![CDATA[ …code… //]]> </script> </svg>
In which case, the JavaScript is just as effectively written outside the SVG, elsewhere in the page:
<html lang="en"> <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 500 500"> … </svg> <script> … </script> </html>
- Alternatively, you can reference the SVG as an
<object>
or<iframe>
inside the HTML:<object data="getfunky.svg" type="image/svg+xml"> <img src="fallback.jpg"> </object>
In either case, JavaScript inside the SVG will be respected and run, influencing the vector data.
Enjoy this piece? I invite you to follow me at twitter.com/dudleystorey to learn more.