使用JavaScript在HTML中动态创建SVG元素

94

我想在HTML页面中创建一个矩形,然后在该矩形上写一些文本。我还需要将该文本设置为超链接。这是我的代码,但它不起作用:

    <!DOCTYPE html>
<html>
<body>

<script>

    var svg   = document.documentElement;
    var svgNS = svg.namespaceURI;

    var rect = document.createElementNS(svgNS,'rect');
    rect.setAttribute('x',5);
    rect.setAttribute('y',5);
    rect.setAttribute('width',500);
    rect.setAttribute('height',500);
    rect.setAttribute('fill','#95B3D7');
    svg.appendChild(rect);
    document.body.appendChild(svg);

    var h=document.createElement('a');
    var t=document.createTextNode('Hello World');
    h.appendChild(t);
    document.body.appendChild(h);


</script>

</body>
</html>

请问您需要帮忙吗?感谢。


1
可能是使用JavaScript创建SVG标签的重复问题。 - Zeimyth
2
楼主,请采纳一个答案或者解释缺失了什么。 - Denys Séguret
5个回答

142

变更

var svg   = document.documentElement;

var svg = document.createElementNS("http://www.w3.org/2000/svg", "svg");

为了创建一个 SVG 元素。

要使链接成为超链接,只需添加一个 href 属性:

h.setAttributeNS(null, 'href', 'http://www.google.com');

演示


1
好的,我会的。这段文本可以正常显示,但是我想改变它的位置。例如,我希望它在矩形中间显示。 - user2746087
请注意,链接是一个HTML锚标签,如果您想将其放在SVG内部,则需要创建一个svg:text元素(在SVG命名空间中),以及一个svg:a元素,然后将它们附加到SVG上。例如,请参见https://dev59.com/HHfZa4cB1Zd3GeqPSYGF。 - Erik Dahlström

56

为了方便编辑 SVG,您可以使用一个中间函数:

function getNode(n, v) {
  n = document.createElementNS("http://www.w3.org/2000/svg", n);
  for (var p in v)
    n.setAttributeNS(null, p, v[p]);
  return n
}

现在你可以这样写:
svg.appendChild( getNode('rect', { width:200, height:20, fill:'#ff0000' }) );

示例(改进的 getNode 函数允许使用连字符属性的驼峰式写法,例如 strokeWidth > stroke-width):

function getNode(n, v) {
  n = document.createElementNS("http://www.w3.org/2000/svg", n);
  for (var p in v)
    n.setAttributeNS(null, p.replace(/[A-Z]/g, function(m, p, o, s) { return "-" + m.toLowerCase(); }), v[p]);
  return n
}

var svg = getNode("svg");
document.body.appendChild(svg);

var r = getNode('rect', { x: 10, y: 10, width: 100, height: 20, fill:'#ff00ff' });
svg.appendChild(r);

var r = getNode('rect', { x: 20, y: 40, width: 100, height: 40, rx: 8, ry: 8, fill: 'pink', stroke:'purple', strokeWidth:7 });
svg.appendChild(r);


2
请注意,如果您尝试设置属性“viewBox”,则“camelcase to dash”功能会使事情变得混乱。 - Chris K
你说得对,我们应该处理一些异常来使其正常工作。 - Joseph Merdrignac
5
@chris 我们可以直接写"stroke-width":2测试过了,效果很好。在属性名称中如果有破折号,就需要使用引号,而不是在v[p]之前添加replace函数。同时,未加引号的简单属性和带引号的带破折号属性也可以混合使用。 - Cee McSharpface

44

将此添加到HTML中:

<svg id="mySVG" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"/>

尝试使用这个函数并根据您的程序进行适应:

var svgNS = "http://www.w3.org/2000/svg";  

function createCircle()
{
    var myCircle = document.createElementNS(svgNS,"circle"); //to create a circle. for rectangle use "rectangle"
    myCircle.setAttributeNS(null,"id","mycircle");
    myCircle.setAttributeNS(null,"cx",100);
    myCircle.setAttributeNS(null,"cy",100);
    myCircle.setAttributeNS(null,"r",50);
    myCircle.setAttributeNS(null,"fill","black");
    myCircle.setAttributeNS(null,"stroke","none");

    document.getElementById("mySVG").appendChild(myCircle);
}     

-1

可以使用片段轻松添加元素。

例子

<input style="width:300px" type="text" placeholder="Input something to change the text." /><br>
<script>
const frag = document.createRange().createContextualFragment(`
<svg width="250" height="250">
  <rect x="0" y="0" width="250" height="250" fill="#95B3D7"></rect>
  <a href="https://www.google.com" style="cursor: pointer" target="_blank">
    <text x="10" y="130" style="
      font-size: 48px;
      fill:#faff00;">
      Hello world</text>
  </a>
</svg>
      `)
      const textElem = frag.querySelector("text")
      document.querySelector("input").onchange = (e) => {
        textElem.textContent = e.target.value
      }
      document.body.append(frag)
</script>


-4

function getNode(n, v) {
  n = document.createElementNS("http://www.w3.org/2000/svg", n);
  for (var p in v)
    n.setAttributeNS(null, p.replace(/[A-Z]/g, function(m, p, o, s) { return "-" + m.toLowerCase(); }), v[p]);
  return n
}

var svg = getNode("svg");
document.body.appendChild(svg);

var r = getNode('rect', { x: 10, y: 10, width: 100, height: 20, fill:'#ff00ff' });
svg.appendChild(r);

var r = getNode('rect', { x: 20, y: 40, width: 100, height: 40, rx: 8, ry: 8, fill: 'pink', stroke:'purple', strokeWidth:7 });
svg.appendChild(r);


1
欢迎来到 Stack Overflow。没有任何解释的代码很少有帮助。Stack Overflow 关注于学习,而不是提供盲目复制粘贴的片段。请编辑您的问题并解释如何回答特定的问题。请参阅 如何回答 - Sfili_81
请删除此答案。这是因为Szin误点击了页面上方的“复制片段到答案”按钮而添加的错误内容。 - Shashank Bodkhe

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