Creating SVG elements dynamically with javascript inside HTML
Change
var svg = document.documentElement;
to
var svg = document.createElementNS("http://www.w3.org/2000/svg", "svg");
so that you create a SVG
element.
For the link to be an hyperlink, simply add a href
attribute :
h.setAttributeNS(null, 'href', 'http://www.google.com');
Demonstration
Create SVG tag with JavaScript
You forgot the Namespace URI of your svg
element and xmlns
attribute.
Also, version
is ignored by all browsers.
var svg = document.createElementNS("http://www.w3.org/2000/svg", "svg");
svg.setAttribute('style', 'border: 1px solid black');
svg.setAttribute('width', '600');
svg.setAttribute('height', '250');
svg.setAttributeNS("http://www.w3.org/2000/xmlns/", "xmlns:xlink", "http://www.w3.org/1999/xlink");
document.body.appendChild(svg);
How to create a valid svg element with javascript
Remove the "s" from "https".
var circle_2 = document.createElementNS('http://www.w3.org/2000/svg','circle');
Even though it looks like a URL. It is really just a string constant that indicates this XML file is an SVG file. The namespace constant has to be exactly as presented here.
Also you need to change circle
to circle_2
for that section of code.
var circle_2 = document.createElementNS('http://www.w3.org/2000/svg','circle');circle_2.setAttribute('cx', '5');circle_2.setAttribute('cy', '20'); circle_2.setAttribute('r', '30');circle_2.setAttribute('fill', 'blue');
var svg = document.getElementById('svgx');var rect = document.getElementById('svgrect');svg.appendChild(circle_2);
<svg style='width: 100%;' id='svgx'><rect x='5' y='5' width='50' height='30' fill='black' id='svgrect'></svg>
How do I add a SVG element using Javascript
To append SVG element you must use createElementNS
with namespace http://www.w3.org/2000/svg
instead createElement
.
document.body.onclick = function() {
console.log("clicked");
var circle = document.createElementNS("http://www.w3.org/2000/svg", "circle");
document.getElementById("svg").appendChild(circle);
circle.setAttribute("cx", 50);
circle.setAttribute("cy", 50);
circle.setAttribute("r", 50);
circle.setAttribute("fill", "blue");
}
<!DOCTYPE html>
<html>
<body>
<svg id="svg" width="100" height="100"></svg>
</body>
</html>
Create SVG Element from String and append it to Div Element
I don't know how to make the method you've been trying work, but there's a much simpler way: put everything in innerHTML
and let the browser sort out the details.
<html>
<body>
<h2>Boolean Network</h2>
<button type="button" onclick="appendSVG('svgAnchor', svgStr)">Next</button>
<div id="svgAnchor" value="3">
</div>
<script>
var svgStr = '<svg width="100" height="100"><circle cx="50" cy="50" r="40" stroke="green" stroke-width="4" fill="yellow"/>';
function appendSVG(id, xml_string){
var el = document.getElementById(id)
el.innerHTML = xml_string;
}
</script>
</body>
</html>
Create svg element from string
For modern browsers* you can use html()
for appending the whole string to your <g>
element.
Here is a basic demo. We first create the <g>
element, then translate it by the value you want, and finally we use the string from the database:
const string = `<desc> <Insert x='21' y='21'></Insert> <Pins> <Pin Id='1' x='21' y='1' direction='up'/> <Pin Id='2' x='21' y='41' direction='down'/> </Pins> <Properties> <Property Id='20010' x='0' y='21' angle='0'></Property> </Properties></desc><circle class='CDC300' cx='21' cy='21' r='20' fill='blue'></circle><polyline class='CDC300' points='1 21 21 1 41 21' fill='red' /><text id='20010' class='CDC400' text-anchor='end' x='-2' y='25' >#{BMK}</text>`;
const svg = d3.select("svg");
const g = svg.append("g").attr("transform", "translate(100,50)");
g.html(string);
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/5.7.0/d3.min.js"></script><svg></svg>
Populate object tag with SVG code with javascript
There are several ways to do it, but they will not all allow you to access to the object's contentDocument...
The easiest one is to convert your SVG markup to a data-URI.
But browsers will then consider this document as being a cross-origin resource, and will then forbid you to access it through js.
// an svg stringconst svgStr = `<svg width="120" height="120" viewBox="0 0 120 120" xmlns="http://www.w3.org/2000/svg">
<rect x="10" y="10" width="100" height="100"/></svg>`;// as dataURIconst dataURI = 'data:image/svg+xml;charset=utf8, '+ encodeURIComponent(svgStr);obj.data = dataURI;
// do some checks after it has loadedobj.onload = e => { console.log('loaded'); try{ console.log(obj.contentDocument.documentElement.nodeName); } catch(err){ console.log('but cant access the document...'); console.error(err); }};
<object id="obj"></object>
Why is it necessary to use `document.createElementNS` when adding `svg` tags to an HTML document via JS?
If you call document.createElement("a") which <a>
should it create? The HTML one or the SVG one? There lies the problem. Ditto script etc. You're not giving the browser any way to guess till the appendChild step and by then it's too late.
You can do this without namespaces via innerHTML because that takes a string with all the markup so the browser can parse and add in one step and thereby infer the correct namespace.
Or just create a wrapper function
function createSVGElement(tag) {
return document.createElementNS('http://www.w3.org/2000/svg', tag)
}
Related Topics
How to Add an Object to an Array
How to Toggle an Element's Class in Pure JavaScript
How to Extract the Hostname Portion of a Url in JavaScript
Chrome Extension - Sendresponse Not Waiting for Async Function
How to 'Minify' JavaScript Code
"Object Doesn't Support This Property or Method" Ie10/11
How to Extend Function with Es6 Classes
Check If Every Element in One Array Is in a Second Array
ASP.NET Postback with JavaScript
How to Call 3 Functions in Order to Execute Them One After the Other
How Many Bytes in a JavaScript String
How to Check If Iframe Is Loaded or It Has a Content
Object Method with Es6/Bluebird Promises