13.4 Scripting SVG
13.4.4 Changing Attributes of Multiple Objects
Claude Opus 4.5 about scripting inside or outside svg
When to put script inside vs outside SVG
| Scenario | Script Location | Reason |
|---|---|---|
| SVG inline in HTML | Outside SVG | Cleaner, better IDE support, standard HTML practice |
Standalone .svg file |
Inside SVG | The .svg file needs to be self-contained |
SVG loaded via <object> or <iframe> |
Inside SVG | Script must be in the SVG file itself |
Benefits of script outside SVG
- No IDE syntax errors — JavaScript is recognized properly
- No CDATA needed — simpler code
- Easier debugging — browser dev tools work better
- Can use modern JS features — modules,
const/let, etc. - Separation of concerns — markup and logic are separate
Since the SVG is inline in HTML, the external script can access all SVG elements via document.getElementById() just like any other DOM element. There's no difference in functionality.
<svg id="shirtSvg" width="300" height="250" viewBox="0 0 300 250"
xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink">
<defs>
<style type="text/css">
svg { /* default values */
stroke: black;
fill: white;
}
g.selected rect {
fill: #ffc; /* light yellow */
}
text {
stroke: none;
fill:black;
text-anchor: middle;
}
</style>
<path id="shirt-outline"
d="M -6 -30 -32 -19 -25.5 -13 -22 -14 -22 30 23 30
23 -14 26.5 -13 33 -19 7 -30
A 6.5 6 0 0 1 -6 -30"/>
</defs>
<g id="shirt" >
<use xlink:href="#shirt-outline" x="0" y="0"/>
</g>
<g id="scale0" >
<rect x="100" y="10" width="30" height="30" />
<text x="115" y="30">S</text>
</g>
<g id="scale1" class="selected">
<rect x="140" y="10" width="30" height="30" />
<text x="155" y="30">M</text>
</g>
<g id="scale2" >
<rect x="180" y="10" width="30" height="30" />
<text x="195" y="30">L</text>
</g>
</svg>
<script>
var scaleChoice = 1;
var scaleFactor = [2, 2.5, 3];
function init() {
var obj;
for (var i = 0; i < 3; i++) {
obj = document.getElementById("scale" + i);
obj.addEventListener("click", clickButton, false);
}
transformShirt();
}
function clickButton(evt) {
var choice = evt.target.parentNode;
var name = choice.getAttribute("id");
var old = document.getElementById("scale" + scaleChoice);
old.removeAttribute("class");
choice.setAttribute("class", "selected");
scaleChoice = parseInt(name[name.length - 1]);
transformShirt();
}
function transformShirt() {
var factor = scaleFactor[scaleChoice];
var obj = document.getElementById("shirt");
obj.setAttribute("transform",
"translate(150, 150) " +
"scale(" + factor + ")");
obj.setAttribute("stroke-width",
1 / factor);
}
// Initialize when DOM is ready
document.addEventListener("DOMContentLoaded", init);
</script>