Search code examples
javascripthtmlsvg

how to append a <svg> element with vanilla JavaScript?


The following vanilla Javascript code appends a <svg> and a <style> element

var text="";
text=text+"<defs>"
text=text+"<filter id='Matrix' filterUnits='objectBoundingBox' x='0%' y='0%' width='100%' height='100%'>"
text=text+"<feColorMatrix type='matrix' in='SourceGraphic' values='0 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 1 0'/>"
text=text+"</filter>"
text=text+"</defs>"

var tag;
tag = document.createElement("svg");
document.body.appendChild(tag);
tag.innerHTML=text;
tag = document.createElement("style");
document.body.appendChild(tag);
tag.innerHTML="img.free {filter:url('#Matrix')}";

to remove red from the image in the following html code:

<head>
</head>
<body>
<img class="free" src="https://upload.wikimedia.org/wikipedia/commons/thumb/2/2f/Google_2015_logo.svg/500px-Google_2015_logo.svg.png">
</body>

(jsfiddle here)

However, the filter inside the <svg> element is not applied.

Notice that the static version of the page (jsfiddle here) does not have such issue.

How can I inject the <svg> element via Javascript and make the filter working?


Solution

  • SVG elements must be created in the SVG namespace.

    var text="";
    text=text+"<defs>"
    text=text+"<filter id='Matrix' filterUnits='objectBoundingBox' x='0%' y='0%' width='100%' height='100%'>"
    text=text+"<feColorMatrix type='matrix' in='SourceGraphic' values='0 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 1 0'/>"
    text=text+"</filter>"
    text=text+"</defs>"
    
    var tag;
    tag = document.createElementNS("http://www.w3.org/2000/svg", "svg");
    document.body.appendChild(tag);
    tag.innerHTML=text;
    tag = document.createElementNS("http://www.w3.org/2000/svg", "style");
    document.body.appendChild(tag);
    tag.innerHTML="img.free {filter:url('#Matrix')}";
    <head>
    </head>
    
    <body>
      <img class="free" src="https://upload.wikimedia.org/wikipedia/commons/thumb/2/2f/Google_2015_logo.svg/500px-Google_2015_logo.svg.png">
    </body>