Monday, May 20, 2024
 Popular · Latest · Hot · Upcoming
6
rated 0 times [  8] [ 2]  / answers: 1 / hits: 56530  / 8 Years ago, fri, december 23, 2016, 12:00:00

I'm trying to load an external svg file and then write additional SVG elements on top of it. When I do, I get the following error



Failed to execute 'appendChild' on 'Node': Only one element on document allowed



when I inspect within Chrome.


Here's the HTML:


<html>
<head>
<link rel="stylesheet" type="text/css" href="css/index.css">
<title>Hello World</title>
</head>
<body>
<svg xmlns="http://www.w3.org/2000/svg" version="1.1" id="mySvg">
<circle cx="40" cy="30" r="15" fill="#FF00FF"
stroke="#000000" stroke-width="2" />
</svg>
<object data="img/drawing.svg" type="image/svg+xml"
align="center" id="svgDrw" height="80vh"></object>
<script type="text/javascript" src="js/problem.js"></script>
</body>
</html>

Here's problem.js:


var svgXtraDoc;
var d = document.getElementById("svgDrw");

d.addEventListener("load",function(){

// get the inner DOM
svgXtraDoc = d.contentDocument;
// get the inner element by id
svgRect1 = svgXtraDoc.getElementById("MyRect1");
svgRect2 = svgXtraDoc.getElementById("MyRect2");
}, false);


function addRect() {
var svgRect = document.createElementNS("http://www.w3.org/2000/svg",
"rect");
svgRect.setAttribute("x", 100);
svgRect.setAttribute("y", 100);
svgRect.setAttribute("width", 100);
svgRect.setAttribute("height", 100);
svgRect.style.fill = "red";
// mySvg.appendChild(svgRect);
svgXtraDoc.appendChild(svgRect);
}

document.getElementById("mySvg").addEventListener("click", addRect);

... and here's drawing.svg, stripped of some of the Inkscapy cruft:


<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->

<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
width="29.02857mm"
height="37.092064mm"
viewBox="0 0 102.85714 131.42857"
id="svg2"
version="1.1">
<g
id="layer1"
transform="translate(-205.71428,-218.07649)">
<rect
style="stroke:none;fill-opacity:1;fill:#5eb056"
id="MyRect1"
width="102.85714"
height="131.42857"
x="205.71428"
y="218.07649" />
<rect
style="fill:#000000;stroke:none;fill-opacity:1"
id="MyRect2"
width="42.857143"
height="65.714287"
x="231.42857"
y="252.3622" />
</g>
</svg>

The error arises when you click on the circle: the rectangle that should appear within the two-rectangle imported drawing doesn't appear, and the error message "Failed to execute 'appendChild' on 'Node': Only one element on document allowed." is displayed in the console.


If I change this so the rectangle is added to the svg containing the circle, i.e. by uncommenting the line "// mySvg.appendChild(svgRect);", then the rectangle successfully appears.


I also know that the drawing file is successfully loading, because in other code (not included here for brevity reasons) I can change the colors of the rectangles within that file. So it seems that I can access existing elements within the file but not add elements.


Is there something about externally loaded SVGs versus inline SVGs that I'm not taking into account?


One last thing -- this is going into a Cordova app so I'd like to keep it small, so pure JavaScript solutions are preferred. I'll use JQuery or SnapSVG if I have to but it seems my needs are sufficiently simple that it should be possible to do this without external libraries.


More From » svg

 Answers
17

There is a difference between the root node of a document and the document element. What you want is the <svg> document element, but .contentDocument gets you the root node.



The root node is one hierarchy level further up. This means, the <svg> document element resides inside the root node, and the root node may only have this one <svg> child element.



To get the document element, do this:



svgXtraDoc = d.contentDocument.documentElement;

[#59586] Thursday, December 22, 2016, 8 Years  [reply] [flag answer]
Only authorized users can answer the question. Please sign in first, or register a free account.
davisbrandtm

Total Points: 387
Total Questions: 99
Total Answers: 106

Location: Tuvalu
Member since Sat, Feb 11, 2023
1 Year ago
;