- SVG and the DOM
- Simple Animations
- Modifying SVG from JavaScript
- Browser Support
Modifying SVG from JavaScript
As I mentioned earlier, all of the SVG elements are in the DOM. Therefore, you can very easily access them from JavaScript, and even attach events to them, like this:
function load() { circle = document.getElementById('circle'); circle.addEventListener('click', click, false); } function click(e) { alert("Circle clicked!"); }
This code pops up an alert box whenever the user clicks the circle from the previous example. Modifying the DOM is more interesting than just getting events, and you can use exactly the same mechanisms that you would use for modifying other DOM nodes. For example, we can change the color of the circle by setting its fill attribute:
function click(e) { var r = parseInt(Math.random()*255); var g = parseInt(Math.random()*255); var b = parseInt(Math.random()*255); circle.setAttribute("fill", "rgb("+r+","+g+","+b+")"); }
This example sets the circle's color to a random value every time the circle is clicked. You can set any of the other attributes in the same way. More interestingly, you can combine this approach with declarative SMIL animations, inserting a new animation into the DOM tree in response to an event. For example, you might insert an animateColor element into the DOM tree:
function click(e) { var r = parseInt(Math.random()*255); var g = parseInt(Math.random()*255); var b = parseInt(Math.random()*255); var color = "rgb("+r+","+g+","+b+")"; var a = document.createElementNS("http://www.w3.org/2000/svg", "animateColor"); a.setAttribute("attributeName", "fill"); a.setAttribute("attributeType", "CSS"); a.setAttribute("dur", "1s"); a.setAttributeNS(null, "begin", "indefinite"); a.setAttribute("from", color); a.setAttribute("to", "white"); a.setAttribute("fill", "freeze"); a.setAttribute("onend", "this.parentNode.removeChild(this);"); circle.appendChild(a); a.beginElement(); }
You need to remember a few things here:
- Use createElementNS() rather than createElement() when you create SVG elements, to ensure that the object that you create is an SVG element and not an HTML element.
- Call beginElement(); on the created animation to make it begin running.
- The most important thing to remember is to avoid memory leaks. This example script adds an onend event handler to destroy the animation object, but this event isn't part of the standard. For portable code, you should request a timer event at the end of the animation and then remove it. Otherwise, your DOM tree will gain a new animation object for every click.
Because SVG is a declarative language, you don't need to keep track of your drawing objects anywhere outside of the DOM, and you don't need to work out what needs redrawing when you make this kind of change; the browser does it all for you. In theory, SVG performance can be better than JavaScript and canvas performance, because more of the drawing time is spent running native code in the browser, rather than interpreted or JIT-compiled JavaScript code.