How to redraw SVG after change from javascript (Internet Explorer and Edge)
Asked Answered
S

4

13

Does anyone know how to force IE and Edge to display/refresh embedded SVG after changing its content (see code below)

<!DOCTYPE html>
<html>
    <head>
        <meta charset="utf-8" />
        <title>Title</title>
        <script type="text/javascript">     
            function onClick() {           
                document.getElementById('svg').innerHTML = '<circle r="50" cx="50" cy="50" fill="red" />';
            }
        </script>
    </head>
    <body>  
        <button type="button" onclick="onClick()" >Display red circle</button>
        <svg id="svg"/>
    </body>
</html>
Sthilaire answered 31/3, 2016 at 17:0 Comment(0)
C
1

Basically, you do not need to reload anything. Actually, the problem is different. You will not able to interact with SVG using standard innerHTML method. Your SVG is not updated after calling to innerHTML. This method is suitable for editing HTML elements only.

Plase take a look at this: update SVG dynamically

Cicero answered 31/3, 2016 at 19:57 Comment(3)
It used to be unsuitable but the specification changed and it should now work with SVG elements. Chrome and Firefox have implemented the new specification but IE and Safari have not yet done so.Lenorelenox
@RobertLongson, that is right. This was the main reason I asked that question. Thank you.Sthilaire
The answer this answer links to consists of just links itself =-DQuip
Q
13

As it was mentioned by @rzelek, SVG image will get updated on it's own if you add elements with svg.appendChild() rather than by assigning to svg.innerHTML.

One caveat, though: you must specify the http://www.w3.org/2000/svg namespace on the element you create using document.createElementNS(), instead of the normal createElement().

Example:

const circle = document.createElementNS('http://www.w3.org/2000/svg', 'circle');
circle.setAttribute('r', '50');
circle.setAttribute('cx', '50');
circle.setAttribute('cy', '50');
circle.setAttribute('fill', 'red');
document.getElementById('svg').appendChild(circle);

JSFiddle

Quip answered 15/4, 2020 at 19:17 Comment(0)
G
11

Modify your markup as

<div id="container">
  Your svg here
</div>

and add

document.getElementById("container").innerHTML += "";

at the end of your script.

Galcha answered 7/7, 2019 at 16:14 Comment(1)
Lol, it actually worked. Though in my case this was required because I used document.createElement() instead of document.createElementNS()Quip
C
1

Basically, you do not need to reload anything. Actually, the problem is different. You will not able to interact with SVG using standard innerHTML method. Your SVG is not updated after calling to innerHTML. This method is suitable for editing HTML elements only.

Plase take a look at this: update SVG dynamically

Cicero answered 31/3, 2016 at 19:57 Comment(3)
It used to be unsuitable but the specification changed and it should now work with SVG elements. Chrome and Firefox have implemented the new specification but IE and Safari have not yet done so.Lenorelenox
@RobertLongson, that is right. This was the main reason I asked that question. Thank you.Sthilaire
The answer this answer links to consists of just links itself =-DQuip
N
0

Plunker

JS:

var x = 0; 

function onClick() {        
  var div = document.getElementById('svg');
  Update(div);
}

function Update(div){

  x++;

  div.innerHTML = '<svg><circle r="' + x + '" cx="' + x +'" cy="' + x + '" fill="red" /></svg>';

  if (x < 100)
  {
    setTimeout(function() {
      Update(div);
    }, 100);  
  }

  console.log(div.innerHTML);
}

HTML:

<body>
  <button type="button" onclick="onClick();" >Display red circle</button>
    <div id="svg">
    </div>
</body>

Wrapping the SVG in a container and then updating the content of the container seems to work.

Napoli answered 31/3, 2016 at 17:52 Comment(8)
It does not solve my problem because I have to update a part of a SVG only. BTW. How could I get content of the SVG? It seems document.getElementById('svg').innerHTML does not workSthilaire
I updated plunk. I can get the current innerHTML of the div containing the SVG. I can Set the content of the div containing the SVG. I am doing it async, and it is working for me in IE.Napoli
I see... but is there a way to get/set the content (I don't know - innerHTML, innerText, etc.) of a <svg> tag? I can't use <div> ...Sthilaire
It would appear that you can change the content of the tag all day, but IE doesn't care to pass this update along to your eyeballs. Which is the reason you're asking this question in the first place, no?Napoli
Yes, I really want to know why it behaves like that. But to be hones, I am rather looking for a workaround ot that "feature".Sthilaire
https://mcmap.net/q/904634/-update-svg-dynamically That seems to really be what you want to do.Napoli
@PiotrAntoniak innerHTML on Safari and IE add the content into the html namespace always instead of inferring the correct namespace from the container element.Lenorelenox
@Max Sorin. Finally I used your solution. ThanksSthilaire

© 2022 - 2024 — McMap. All rights reserved.