JavaScript createElement和SVG

JavaScript createElement and SVG

我想使用Javascript创建内联SVG图形。

但是,似乎createElementNS函数应用了一些规范化并将所有标签转换为小写。 这对于HTML很好,但对XML / SVG则不行。 我使用的NS是http://www.w3.org/2000/svg。

特别是在创建元素时遇到问题。 由于它将被附加为,因此将不起作用。

我进行了一些搜索,但找不到解决方案。

有人知道解决方案吗?

非常感谢!

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

结果是

1
<textpath></textpath>


希望以下示例对您有所帮助:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
function CreateSVG() {
    var xmlns ="http://www.w3.org/2000/svg";
    var boxWidth = 300;
    var boxHeight = 300;

    var svgElem = document.createElementNS(xmlns,"svg");
    svgElem.setAttributeNS(null,"viewBox","0 0" + boxWidth +"" + boxHeight);
    svgElem.setAttributeNS(null,"width", boxWidth);
    svgElem.setAttributeNS(null,"height", boxHeight);
    svgElem.style.display ="block";

    var g = document.createElementNS(xmlns,"g");
    svgElem.appendChild(g);
    g.setAttributeNS(null, 'transform', 'matrix(1,0,0,-1,0,300)');

    // draw linear gradient
    var defs = document.createElementNS(xmlns,"defs");
    var grad = document.createElementNS(xmlns,"linearGradient");
    grad.setAttributeNS(null,"id","gradient");
    grad.setAttributeNS(null,"x1","0%");
    grad.setAttributeNS(null,"x2","0%");
    grad.setAttributeNS(null,"y1","100%");
    grad.setAttributeNS(null,"y2","0%");
    var stopTop = document.createElementNS(xmlns,"stop");
    stopTop.setAttributeNS(null,"offset","0%");
    stopTop.setAttributeNS(null,"stop-color","#ff0000");
    grad.appendChild(stopTop);
    var stopBottom = document.createElementNS(xmlns,"stop");
    stopBottom.setAttributeNS(null,"offset","100%");
    stopBottom.setAttributeNS(null,"stop-color","#0000ff");
    grad.appendChild(stopBottom);
    defs.appendChild(grad);
    g.appendChild(defs);

    // draw borders
    var coords ="M 0, 0";
    coords +=" l 0, 300";
    coords +=" l 300, 0";
    coords +=" l 0, -300";
    coords +=" l -300, 0";

    var path = document.createElementNS(xmlns,"path");
    path.setAttributeNS(null, 'stroke',"#000000");
    path.setAttributeNS(null, 'stroke-width', 10);
    path.setAttributeNS(null, 'stroke-linejoin',"round");
    path.setAttributeNS(null, 'd', coords);
    path.setAttributeNS(null, 'fill',"url(#gradient)");
    path.setAttributeNS(null, 'opacity', 1.0);
    g.appendChild(path);

    var svgContainer = document.getElementById("svgContainer");
    svgContainer.appendChild(svgElem);
}
1
2
3
4
5
#svgContainer {
  width: 400px;
  height: 400px;
  background-color: #a0a0a0;
}
1
2
3
<body onloadx="CreateSVG()">
   
</body>


首先,像您一样使用createElementNS。根据Mozilla文档,createElement(不带NS)自动将HTML文档中的元素名称小写。

其次,不要在这里信任Google Chrome的"检查元素"功能。无论实际的nodeName是什么,它似乎都以小写形式显示每个元素。尝试这个:

1
2
3
4
5
document.createElementNS("http://www.w3.org/2000/svg","textPath").nodeName
// Output:"textPath"

document.createElement("textPath").nodeName
// Output:"TEXTPATH"

您的问题可能是无关的问题。例如,此代码在Firefox中可以正常工作,但在Chrome(12.0.742.112)中会损坏:

1
2
3
4
5
6
7
8
9
10
11
12
13
function animateSVG() {
  var svgNS ="http://www.w3.org/2000/svg";
  var textElement = document.getElementById("TextElement");
  var amElement = document.createElementNS(svgNS,"animateMotion");
  console.log(textElement);
  console.log(amElement);
  console.log(amElement.nodeName);
  amElement.setAttribute("path","M 0 0 L 100 100");
  amElement.setAttribute("dur","5s");
  amElement.setAttribute("fill","freeze");
  textElement.appendChild(amElement);
  //amElement.beginElement();
};
1
2
3
4
5
6
7
8
9
10
<body onloadx="animateSVG()">
  <svg width="100%" height="100%" version="1.1" xmlns="http://www.w3.org/2000/svg">
    <g transform="translate(100,100)">
      <text id="TextElement" x="0" y="0" style="font-family:Verdana;font-size:24">
        It's SVG!
        <!--  -->
      </text>
    </g>
  </svg>
</body>

我的问题可能与Chrome中animateMotion的处理不当有关(问题13585)。

您的问题可能相同,也可能是另一个问题,但是请确保您没有被元素检查器所欺骗。


我刚刚解决了一个类似的问题。
当从HTML页面调用document.createElement(我假设为document.createElementNS)时,它会创建一个HTML节点(大小写无关紧要),而不是xml节点。

以下在Chrome中有效:

doc = document.implementation.createDocument(null,null,null);
doc.createElementNS(" http://www.w3.org/2000/svg"," textPath");

您将获得混合大小写的节点。


给出的答案过于广泛,对我而言并没有真正的用处,我觉得这很麻烦或只是说假。如果我是你,我会简单地将html中的元素标记为:

1
<b id="myElement">

当我必须创建元素或添加信息时,我只需执行以下操作:

1
document.getElementById('myElement').innerHTML = 'your stuff here';

希望对您有所帮助。