JavaScript createElement和SVG

时间:2010-08-16 10:29:58

标签: javascript svg capitalization

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

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

特别是我在创建元素时遇到了问题。因为它将被附加,因此将无法工作。

我做了一些搜索,但还没找到解决方案。

有人知道解决方案吗?

非常感谢!

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

结果

<textpath></textpath>

4 个答案:

答案 0 :(得分:37)

我希望,以下示例可以帮助您:

<head>
    <style>
        #svgContainer {
            width: 400px;
            height: 400px;
            background-color: #a0a0a0;
        }
    </style>
    <script>
        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);         
        }

    </script>
</head>
<body onload="CreateSVG ()">
    <div id="svgContainer"></div>
</body>

答案 1 :(得分:11)

首先,使用createElementNS,就像你一样。根据{{​​3}},createElement(不带NS)自动缩小HTML文档中的元素名称。

其次,请不要相信Google Chrome的“Inspect Element”功能。无论实际的nodeName是什么,它似乎都以小写形式显示每个元素。试试这个:

  > document.createElementNS("http://www.w3.org/2000/svg", "textPath").nodeName
  "textPath"
  > document.createElement("textPath").nodeName
  "TEXTPATH"

您的问题可能是一个无关的问题。例如,此代码在Firefox中运行良好,但在Chrome中断(12.0.742.112):

<html>
  <head>
      <script>
        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();
        };
      </script>
  </head>
  <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>
</html>

我的问题可能与Chrome中的animateMotion处理失败有关(Mozilla documentation)。

您的问题可能相同,或者可能是另一个问题,但请确保您不会被元素检查员愚弄。

答案 2 :(得分:3)

我刚刚解决了类似的问题。 document.createElement(我假设是document.createElementNS),当从HTML页面调用时创建一个HTML节点(在这种情况下无关紧要),而不是一个xml节点。

以下适用于Chrome:

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

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

答案 3 :(得分:-4)

给出的答案过于广泛,对我来说并不是真正有用,我发现它很麻烦或者只是说虚假。如果我是你,我会简单地用html中的元素标记说:

<b id="myElement"></b>

当我必须创建元素或添加信息时,我会这样做:

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

我希望这很有帮助。