JavaScript createElement и SVG - PullRequest
       3

JavaScript createElement и SVG

26 голосов
/ 16 августа 2010

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

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

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

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

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

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

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

результат в

<textpath></textpath>

Ответы [ 4 ]

40 голосов
/ 16 августа 2010

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

<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>
11 голосов
/ 06 июля 2011

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

Во-вторых, не доверяйте функции "Проверка элемента" в Google Chrome.Кажется, что каждый элемент отображается в нижнем регистре, независимо от того, каково действительное имя узла.Попробуйте это:

  > 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 ( Issue 13585)).

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

2 голосов
/ 17 октября 2012

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

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

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

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

0 голосов
/ 19 мая 2011

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

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

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

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

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...