0

I'm loading circle.svg in to a svg's group and want to access circle's elements (minus or svgbar). Anything within the circle.svg comes up as null or undefined though.

I tried loading it as an object but it doesn't even load the image. I tried searching through the contentDocument but contentDocument is undefined.

Any help will be appreciated.

circle.svg's content:

<?xml version="1.0" encoding="utf-8"?>    
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN"    "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg id="minus" xmlns="http://www.w3.org/2000/svg" width="32px" height="32px" >
<circle id="svgbar" cx="16" cy="16" r="16" />
<rect id="iline" x="8" y="14" fill="#F9F9F9" width="16" height="4" />
</svg>

html:

<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="utf-8">
        <title>How to access externally loaded svg elements</title>

        <script src="http://d3js.org/d3.v3.min.js" charset="utf-8"></script>
    </head>

    <body>

        <script type="text/javascript">

            var vis = d3.select( "body" ).append( "svg" ).attr( "id", "svgObj" );
            var grp = vis.append( "g" ).attr( "id", "grp" );

            /*var img = grp.append( "object" )
                    .attr( "type", "image/svg+xml" )
                    .attr( "data", "imgs/nav/circle.svg" );*/

            var img = grp.append( "image" )
                    .attr( "id", "collapse" )
                    .attr( "xlink:href", "imgs/nav/circle.svg" );

                    img.attr( "height", 20 )
                    .attr( "width", 20 )
                    .on( "mouseover", function() {

                        console.log( "overing..." );
                    } );


            var befSvgObj = document.getElementById('svgObj');
            console.log( "befSvgObj: " + befSvgObj );

            // wait until all the resources are loaded
            window.addEventListener( "load", findSVGElements, false);           

            function findSVGElements()  {

                var contDoc = befSvgObj.contentDocument;

                var svgObj = document.getElementById('svgObj');
                var gObj = document.getElementById( 'grp' );
                var cObj = document.getElementById( 'collapse' );
                            var svgBar = document.getElementById( 'svgBar' );
                var minus = document.getElementById('minus'); // null
                //var minus2 = cObj.contentDocument.getElementById( 'minus' );
                 // Cannot call method 'getElementById' of undefined

                console.log( "svgObj: " + svgObj );
                console.log( "gObj: " + gObj );
                console.log( "cObj: " + cObj );
                console.log( "minus: " + minus );

                console.log( "svgObj.contentDocument: " + svgObj.contentDocument );
                console.log( "gObj.contentDocument: " + gObj.contentDocument );
                console.log( "cObj.contentDocument: " + cObj.contentDocument );
                console.log( "contDoc: " + contDoc );
                            console.log( "svgBar: " + svgBar );

            }


        </script>

    </body>
</html>     

s

Mindgnosis
  • 37
  • 6

1 Answers1

2

If you embed an external SVG as an image, that's all you get -- the image, you cannot modify it anymore than you could a PNG or JPEG image. Read the W3 specs for more.

If you need to access or modify the content of the external SVG, this answer describes how to read the external file as XML and insert it in your current document.

Community
  • 1
  • 1
AmeliaBR
  • 27,344
  • 6
  • 86
  • 119
  • Thanks, I can see it in my Elements debug now but still not able to access the svg elements using document.getElementById nor contentDocument.getElementById – Mindgnosis Feb 04 '14 at 10:10
  • Are you still calling your `findSVGElements` method in a window load event? Because you have to wait until *after* `d3.xml` has triggered its asynchronous callback method. That's the only reason I can think why `document.getElementById()` would fail. (Well, that or a conflict between `id` values between the inserted content and the rest of the document -- but you seem to have unique values in your example.) `contentDocument` will fail because this isn't an embedded object, there is no content document: see [this MDN article](https://developer.mozilla.org/en-US/docs/Web/SVG/Scripting) – AmeliaBR Feb 04 '14 at 16:27
  • Thanks! That was part of it. I'm able to retrieve the svg element now "minus", but still not its content "svgbar". See the [jsbin](http://jsbin.com/IneBoGOt/1/edit?html,js,console) – Mindgnosis Feb 05 '14 at 01:39
  • The bin doesn't work because of cross-origin access errors, but I'm pretty sure the problem's a simple typo: "svgBar" vs "svgbar". – AmeliaBR Feb 05 '14 at 02:09
  • You are awesome! I'm so embarrassed :) – Mindgnosis Feb 05 '14 at 03:09