如何在 JavaScript 中更改 SVG 后重新绘制 (Internet Explorer 和 Edge)?

11

有人知道如何强制IE和Edge在更改其内容后显示/刷新嵌入式SVG吗(请参见以下代码)

<!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>
4个回答

10
如@rzelek所提到的那样,如果你使用svg.appendChild()添加元素而不是通过赋值svg.innerHTML来更新SVG图片,它将自动更新。
但需要注意的是: 你必须在使用document.createElementNS()创建元素时,在元素上指定命名空间http://www.w3.org/2000/svg,而不是普通的createElement()
例如:
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


10

请修改你的标记:

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

并添加
document.getElementById("container").innerHTML += "";

在你的脚本结尾处。

2
哈哈,它真的起作用了。虽然在我的情况下这是必需的,因为我使用了 document.createElement() 而不是 document.createElementNS() - Klesun

1
基本上,您不需要重新加载任何内容。实际上,问题是不同的。您将无法使用标准的 innerHTML 方法与 SVG 进行交互。在调用 innerHTML 后,您的 SVG 不会更新。此方法仅适用于编辑 HTML 元素。
请看这个链接:update SVG dynamically

以前不适用,但规范已更改,现在应该可以与SVG元素一起使用。Chrome和Firefox已经实现了新规范,但IE和Safari尚未这样做。 - Robert Longson
1
@RobertLongson,没错。这就是我问那个问题的主要原因。谢谢。 - Piotr Antoniak
2
这个答案链接指向的内容只包含其他链接 =-D - Klesun

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>

将SVG放入容器中,然后更新容器的内容似乎是可行的。

它并不能解决我的问题,因为我只需要更新SVG的一部分。顺便问一下,我该如何获取SVG的内容?似乎document.getElementById('svg').innerHTML不起作用。 - Piotr Antoniak
我更新了 plunk。我可以获取包含 SVG 的 div 的当前 innerHTML。我可以设置包含 SVG 的 div 的内容。我正在异步地执行它,并且在 IE 中对我有效。 - Max Sorin
看起来你可以整天更改标签的内容,但IE不关心将此更新传递给你的眼睛。这就是你首先提出这个问题的原因,不是吗? - Max Sorin
是的,我真的想知道为什么它会表现出那样的行为。但说实话,我更想寻找一个解决那个“特性”的方法。 - Piotr Antoniak
@PiotrAntoniak 在Safari和IE上,innerHTML总是将内容添加到html命名空间中,而不是从容器元素推断正确的命名空间。 - Robert Longson
显示剩余3条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接