如何使用JavaScript或jQuery动态添加SVG图形?

8

我正在尝试在页面加载后或仅在页面加载时创建SVG标记结构。

这个请求可能看起来很奇怪,但这是必需的,因为大部分HTML标记是由已编译的作者软件应用程序生成的,所以我不能篡改它。我只能“注入”javascript来根据需要创建其他资产(例如:Divs)。

请参见下面的标记。[出于清晰起见,已省略了部分HTML标记。]

<html>
....
<script>
function run()  {
var newSvg = document.getElementById('myDiv'); 
newSvg.outerHTML+='<svg  style="position:absolute;z-index:10;margin:0;padding:0;top:0em;left:0.5em" onclick="go()" width="100" height=100><circle cx="400" cy="400" r="40" stroke="red" stroke-width="4" fill="blue" />';
}
</script>
<body>
....
<div id="myDiv"></div>
....
<script>
run();
</script>
</body>
</html>

如果我手动将SVG标记放在目的地位置,页面和SVG会正确地呈现。如果我尝试动态创建标记,就什么都没有出现。
当页面加载后查看HTML源代码时,应该由函数创建的SVG没有标记。
我已经尝试通过事件进行操作,但它也不起作用。
请注意:当我需要动态创建新的DIV时,这个函数可以很好地工作。
我做错了什么?提前感谢大家。

我刚刚编辑了我的回答并添加了一些更多的信息,请看看是否适合您。 - t1nr2y
你使用的是哪个浏览器?Safari和IE不支持使用outerHTML创建SVG内容。 - Robert Longson
它是在IE上(项目要求),但我很失望现在它在Firefox上不起作用。我已经让它在IE上工作了(我想)。我希望它能在IE和FF上运行。谢谢提醒。 - MarkL
我已经在FF中让它工作了。我忘记包含xmlns="http://www.w3.org/2000/svg"以使用正确的命名空间。IE 11现在似乎并不关心。 - MarkL
4个回答

18
你所做的是完全正确的。你的svg中有一些小缺陷,导致它无法显示。
  1. 正如t1nr2y所指出的那样,请使用正确的命名空间(xmlns="http://www.w3.org/2000/svg")
  2. svg的height属性缺少引号(height="100")
  3. 你的svg元素没有结束标记(缺少</svg>)
  4. 你的圆形远超出了可视区域(width="100" height="100",但cx="400" cy="400")

var newSvg = document.getElementById('myDiv');
newSvg.outerHTML += '<svg xmlns="http://www.w3.org/2000/svg" style="position:absolute;z-index:10;margin:0;padding:0;top:0em;left:0.5em" onclick="go()" width="100" height="100"><circle cx="40" cy="40" r="40" stroke="red" stroke-width="4" fill="blue" /></svg>';
<div id="myDiv"></div>


感谢您的反馈。我已经进行了您提到的所有更正,甚至使用了您的代码,但仍然无法渲染。我认为t1nr2y可能是对的。我将研究这个方面。 - MarkL

8
JavaScript for SVG有些不同,因为它们在不同的命名空间中。在快速研究中,我找不到确切的学习来源,但我找到了一个旧的SO问题,其中显示了创建方式略有不同。由于我个人没有进行过研究,所以我只能建议outerHTML函数无法工作,您必须找到SVG命名空间的等效函数。尝试在w3.org网站上进行更多信息的研究。

编辑: 经过进一步的研究,请尝试创建您的SVG元素(而不是使用字符串)。

例如:

  var svg = document.createElementNS("http://www.w3.org/2000/svg", "svg");
  svg.setAttribute("width", "640");
  ...
  document.getElementById("div").appendChild(svg);

感谢您的反馈。我会研究那个角度。 - MarkL
我会尝试一下。我思考了一下,感觉虽然有命名空间的问题,但现在我更倾向于这个问题与时间有关。调用(newSvg.outerHTML +='...string...')只是将一个html标签(mydiv)与一个字符串(my SVG markup)连接起来。它应该至少出现在我的渲染页面的源代码中。但它没有。这就是为什么我认为它与时间有关。为了测试我的理论,在(newSvg.outerHTML+=)调用之前我放置了一个警报,现在我可以正确地呈现SVG。 - MarkL
@MarkL,时间问题确实有道理,我试图弄清楚其他答案在它们的代码片段中是如何工作的,而你的为什么不行。我会研究一下SVG的时间问题,如果我找到任何有用的东西,我会告诉你。 - t1nr2y
谢谢。这些页面的行为似乎已经正常化,甚至时间问题似乎也消失了[不确定为什么;也许我们的服务器今天更加响应...] - MarkL
我注意到一件事情。当我手动将SVG标记放在页面上时,如果我忘记引号,IE会有些宽容,这意味着它仍然可以正确渲染SVG。但是,如果在“newSvg.outerHTML + =”中缺少引号,则根本无法呈现。由于我的SVG标记来自另一个应用程序创建的SVG(我使用Inkscape生成SVG标记),因此在复制粘贴、删除Inkscape生成的SVG标记中的空格、制表符和换行符时,我必须特别小心。 - MarkL
显示剩余2条评论

0

你的SVG尺寸(100 x 100)比你的圆的位置小。

$(document).ready(function() {
  $('#myDiv').append('<svg  style="position:absolute;z-index:10;margin:0;padding:0;top:0em;left:0.5em" onclick="go()" width="100" height=100><circle cx="4" cy="4" r="4" stroke="red" stroke-width="4" fill="blue" /></svg>');
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="myDiv"></div>


感谢反馈。我做了你和Holger Will提到的所有更正,甚至使用了你的代码,但仍然无法呈现。我认为t1nr2y可能是正确的。我会研究那个问题。 - MarkL

0
var newSvg = document.getElementById('myDiv');
newSvg.innerHTML += ``;

这在所有浏览器上都有效。


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