I\'m loading an SVG through an object tag and need to access SVG\'s elements (to manipulate them). How can I do that?
Here\'re partial solutions I\'m aware of:
Here's a technique I have used successfully, mentioned in the (very good) O'Reilly "SVG Essentials" book:
Add JavaScript code to your SVG document itself and handle the load event on the root svg element.
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" onload="init(evt)">
<script type="text/ecmascript" xlink:href="svgScript.js" />
In this svgScript.js load event handler, write out whatever you need to expose to the HTML-side script through the built-in parent
variable.
function init(evt) {
svgDocument = evt.target.ownerDocument;
parent.theSvgDocument = svgDocument;
}
Back in your HTML-side script, you can now directly access and use this reference.
var svgDocument = theSvgDocument;
In this example we expose the SVG Document object but you could pass on any object or a function. In my project I actually exposed some kind of controller object reference so that my SVG-side script contains all the logic for manipulating the SVG document, and the HTML-side script merely grabs this controller object and calls public methods on it.
I tried different combinations/solutions suggested here/elsewhere, and looks like the best way to handle SVG is to embed the SVG element in the HTML - just make sure you name it as .xhtml. Once you do that, you can simply navigate the DOM and do what you want (like yankee suggested).
I've verified that this works in the current versions of Chrome, FF, Safari, IE, and Opera. It also works in IE8. Below is a rough example that has a button and a gradient bar - if you click on the button, it turns the bar red.
<button style="display: block;" onclick="document.getElementById('color').setAttribute('style', 'stop-color:#FF0000');">Color</button>
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
width="49px" height="376px" viewBox="0 0 49 376" enable-background="new 0 0 49 376" xml:space="preserve">
<g>
<linearGradient id="SVGID_1_" gradientUnits="userSpaceOnUse" x1="24" y1="376" x2="24" y2="1.0005">
<stop offset="0" style="stop-color:#FFFFFF"/>
<stop id="color" offset="1" style="stop-color:#000000"/>
</linearGradient>
<path fill="url(#SVGID_1_)" d="M48,366c0,5.522-4.477,10-10,10H10c-5.523,0-10-4.478-10-10V11C0,5.477,4.477,1,10,1h28
c5.523,0,10,4.477,10,10V366z"/>
</g>
</svg>
If your option 2) doesn't work, I would like to see your example. What browsers are you testing in? Are you using an svg plugin?
Option 2) is one of the things that the Acid3 test checks for (subtest #74).
Could you use SVGweb? Here's an example of using an 'object' tag. I'm by no means an SVGweb guy, but I'm looking at the example in Chrome inspector and I can see <g>
nodes just fine. (Plus you'd have IE support built in.)
It is another dependency, though (and they also rely on conditional comments for IE, not sure if that is acceptable in your situation).
Alternatively, you could cheat off their source code and see how they do it. (Holy crap, they put tomes of documentation in there!)