JavaScript createElement 和 SVG
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 
原文地址: http://stackoverflow.com/questions/3492322/
Warning: these are provided under cc-by-sa 4.0 license.  You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
JavaScript createElement and SVG
提问by pat
I want to create inline SVG graphics using Javascript.
我想使用 Javascript 创建内联 SVG 图形。
However, it seems like createElementNS function applies some normalization and transforms all tags to lowercase. That is fine for HTML but not for XML/SVG. The NS I used is http://www.w3.org/2000/svg.
但是,似乎 createElementNS 函数应用了一些规范化并将所有标签转换为小写。这适用于 HTML,但不适用于 XML/SVG。我使用的 NS 是http://www.w3.org/2000/svg。
In particular I have problems creating a element. As it will be appended as an thus will not work.
特别是我在创建元素时遇到问题。因为它将被附加为 a 因此将不起作用。
I did some search but could not find a solution yet.
我做了一些搜索,但还没有找到解决方案。
Does anybody know a solution?
有人知道解决方案吗?
Thanks a lot!
非常感谢!
document.createElementNS("http://www.w3.org/2000/svg","textPath");
results in
结果是
<textpath></textpath>
回答by gumape
I hope, the following example will help you:
我希望,下面的例子会帮助你:
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);
}#svgContainer {
  width: 400px;
  height: 400px;
  background-color: #a0a0a0;
}<body onload="CreateSVG()">
    <div id="svgContainer"></div>
</body>回答by dlitz
Firstly, use createElementNS, as you are doing. createElement (without NS) automatically lowercases element names inside HTML documents, according to the Mozilla documentation.
首先,像您一样使用 createElementNS。根据Mozilla 文档,createElement(不带 NS)会自动将 HTML 文档中的元素名称小写。
Secondly, don't trust Google Chrome's "Inspect Element" feature here. It seems to display every element in lowercase, no matter what the actual nodeName is. Try this:
其次,不要相信谷歌浏览器的“检查元素”功能。无论实际的 nodeName 是什么,它似乎都以小写形式显示每个元素。尝试这个:
document.createElementNS("http://www.w3.org/2000/svg", "textPath").nodeName
// Output: "textPath"
document.createElement("textPath").nodeName
// Output: "TEXTPATH"
Your problem might be an unrelated issue. For example, this code works fine in Firefox, but breaks in Chrome (12.0.742.112):
您的问题可能是一个无关的问题。例如,此代码在 Firefox 中运行良好,但在 Chrome (12.0.742.112) 中会中断:
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();
};<body onload="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!
        <!-- <animateMotion path="M 0 0 L 100 100" dur="5s" fill="freeze"/> -->
      </text>
    </g>
  </svg>
</body>My issue probably has something to do with the broken handling of animateMotion in Chrome (Issue 13585).
我的问题可能与 Chrome 中 animateMotion 的处理中断有关(问题 13585)。
Your issue might be the same, or it might be another issue, but make sure you're not being fooled by the element inspector.
您的问题可能是相同的,也可能是另一个问题,但请确保您没有被元素检查器愚弄。
回答by Markus De Freitas
I have just resolved a similar problem. document.createElement (and I assume document.createElementNS), when called from a HTML page creates a HTML node (where case doesnt matter), not an xml node.
我刚刚解决了一个类似的问题。document.createElement(我假设 document.createElementNS),当从 HTML 页面调用时会创建一个 HTML 节点(大小写无关紧要),而不是一个 xml 节点。
The following works in Chrome:
以下在 Chrome 中有效:
doc = document.implementation.createDocument(null, null, null); doc.createElementNS("http://www.w3.org/2000/svg","textPath");
doc = document.implementation.createDocument(null, null, null); doc.createElementNS("http://www.w3.org/2000/svg","textPath");
you will get your mixed case node.
您将获得混合大小写节点。
回答by Johnydep
the answer given is too extensive and not really useful to me and i find it to much troublesome or to simply say bogus. If i were you, i would simple have on element in html with tag say:
给出的答案太广泛了,对我来说并没有什么用,我觉得它很麻烦,或者只是说假的。如果我是你,我会简单地在 html 中的元素上加上标签说:
<b id="myElement"></b>
and when i have to create element or add information i would simply do:
当我必须创建元素或添加信息时,我会这样做:
document.getElementById('myElement').innerHTML = 'your stuff here'; 
I Hope that was helpful.
我希望这是有帮助的。

