JavaScript createElement и SVG

Я хочу создать встроенную графику SVG с помощью Javascript.

однако, похоже, что функция createElementNS применяет некоторую нормализацию и преобразует все теги в нижний регистр. Это хорошо для HTML, но не для XML / SVG. Я использовал NShttp://www.w3.org/2000/svg.

в частности у меня проблемы с созданием элемента. Как это будет добавлено, как таким образом не будет работать.

Я сделал некоторый поиск, но не смог найти решение еще.

кто-нибудь знает решение?

Спасибо большое!

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

результаты

<textpath></textpath>

4 ответов


надеюсь, вам поможет следующий пример:

<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>

во-первых, используйте createElementNS, как вы это делаете. createElement (без NS) автоматически строчные имена элементов внутри HTML-документов, в соответствии с документация Mozilla.

во-вторых, не доверяйте функции "проверить элемент" Google Chrome здесь. Кажется, что он отображает каждый элемент в нижнем регистре, независимо от фактического имени 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>

моя проблема, вероятно, имеет какое-то отношение к сломанной обработке animateMotion в Chrome (вопрос 13585).

ваша проблема может быть такой же, или это может быть другая проблема, но убедитесь, что вас не обманывает инспектор элементов.


Я только что решил подобную проблему. документ.createElement (и я предполагаю документ.createElementNS), при вызове с HTML-страницы создает HTML-узел (где случай не имеет значения), а не xml-узел.

в Chrome работает следующее:

doc = документ.реализация.createDocument(null, null, null); док.createElementNS("http://www.w3.org/2000/svg", "textPath");

вы получите свой узел смешанного случая.


данный ответ слишком обширен и не очень полезен для меня, и я нахожу его очень хлопотным или просто сказать фиктивным. На вашем месте я бы просто поставил на элемент в html с тегом say:

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

и когда мне нужно создать элемент или добавить информацию, я бы просто сделать:

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

Я надеюсь, что это было полезно.