JavaScript createElement и SVG

18

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

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

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

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

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

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

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

приводит к

<textpath></textpath>
    
задан pat 16.08.2010 в 12:29
источник
  • Как вы это узнаете? Как вы сбрасываете созданный элемент в XML-код? Имена тегов XML должны быть чувствительными: ejohn.org/blog/nodename-case-sensitivity –  Pekka 웃 16.08.2010 в 12:41

4 ответа

29

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

<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>
    
ответ дан gumape 16.08.2010 в 13:07
  • Спасибо за ваш ответ. На основе вашего ответа и примера svg от текста к пути: http://pmast.de/svg/textToPath.svg Я создал следующий документ: http://pmast.de/svg/textToPath.html Хотя полученный источник кажется идентичным, и создание элементов следует за вашим примером, мой документ не работает ... Я что-то упустил? –  pat 25.08.2010 в 13:56
  • Ваш пример помог мне начать работу над созданием элементов SVG из JS. Все еще пришлось прочитать документ спецификации W3.org на Core DOM. Пространства имен довольно сбивают с толку. Спасибо за советы. –  CyberFonic 28.04.2012 в 07:24
  • Это работает для людей? Я просто получаю серое поле без каких-либо элементов SVG. (Firefox и Chrome) –  schlingel 18.02.2015 в 15:58
9

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

Во-вторых, не доверяйте функции «Inspect Element» в 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 ( Проблема 13585 ).

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

    
ответ дан dlitz 06.07.2011 в 17:16
  • ваш комментарий о функции проверки элементов хромирования сохранен мой день, спасибо –  ZPiDER 15.10.2013 в 20:01
5

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

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

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

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

    
ответ дан Markus De Freitas 17.10.2012 в 05:24
-4

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

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

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

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

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

    
ответ дан Johnydep 19.05.2011 в 19:43
  • Этот вопрос касается SVG, а не HTML. –  gilly3 22.10.2012 в 02:16
  • @ gilly3 у него есть точка, но принятый ответ предполагает создание элемента SVG DOM в основном с нуля, который, будучи аккуратным, чтобы знать, как это сделать и технически, более правильный ответ, не совсем практичен. Поскольку синтаксис SVG в SVG-файле в основном идентичен синтаксису определения SVG в DOM (из подстроки «<svg»), гораздо практичнее взять элемент контейнера, такой как span или b, и установить его атрибут innerHTML для необработанные данные SVG - браузер позаботится о жестком разборе и строительных работах для вас именно так. Я бы сказал, что это правильный ответ «быстро исправить» –  CCJ 09.07.2015 в 20:04
  • Это довольно конкретный вариант использования - чтобы вся разметка чертежа SVG была как строка и добавила ее как элемент HTML. В частности, возникает вопрос о добавлении элемента SVG к существующему чертежу. Теперь, сегодня вы можете написать innerHTML элемента SVG в некоторых браузерах, но эта функциональность является новой и доступна только с начала этого года. Единственный способ добавить элемент к существующему чертежу в IE сегодня и во всех браузерах в тот момент, когда задавался этот вопрос, - через createElementNS (). –  gilly3 09.07.2015 в 21:03