2010-08-16 45 views
17

我想使用Javascript創建內聯SVG圖形。JavaScript createElement和SVG

但是,它看起來像createElementNS函數應用一些規範化並將所有標記轉換爲小寫。這對HTML而言不錯,對XML/SVG不適用。我使用的NS是http://www.w3.org/2000/svg

尤其是我在創建元素時遇到了問題。因爲它將被附加,因此不起作用。

我做了一些搜索,但還是找不到解決方案。

有沒有人知道解決方案?

非常感謝!

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

結果

<textpath></textpath> 
+0

你如何找出發生這種情況你怎麼轉儲創建的元素到XML代碼的XML標記名稱應敏感:http://ejohn.org/blog/nodename-case-sensitivity/ – 2010-08-16 10:41:37

回答

27

我希望下面的例子將幫助您:

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

感謝您的回覆。根據您的回答和文本到路徑的svg示例:[http://pmast.de/svg/ textToPath.svg](http://pmast.de/svg/textToPath.svg) 我創建了以下文檔:[http://pmast.de/svg/textToPath.html](http://pmast.de/ svg/textToPath.html) 儘管生成的源代碼看起來完全相同,並且元素的創建遵循您的示例,但我的文檔不能正常工作... 我錯過了什麼嗎? – pat 2010-08-25 11:56:29

+0

你的例子幫助我開始從JS創建SVG元素。仍然必須閱讀Core DOM上的W3.org規範文檔。命名空間相當混亂。感謝您的提示。 – CyberFonic 2012-04-28 05:24:09

+1

這是爲人們工作嗎?我只是得到一個沒有任何SVG元素的灰色框。 (Firefox和Chrome瀏覽器) – schlingel 2015-02-18 14:58:55

-4

給出的答案是太廣泛,不是真的有用,我和我這找到很麻煩或簡單地說假。如果我是你,我會簡單的在與標記的HTML元素上說:

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

,當我要創建元素或添加信息,我只想做:

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

我希望這是很有幫助。

+0

這個問題是關於SVG,而不是HTML。 – gilly3 2012-10-22 00:16:43

+0

@ gilly3雖然他有一點 - 接受的答案涉及基本上從頭開始構建一個SVG DOM元素,儘管知道如何做,技術上更正確的答案是不完全實用的。由於SVG文件中的SVG語法與DOM中的SVG定義語法(來自' CCJ 2015-07-09 18:04:22

+1

這是一個非常特殊的用例 - 將整個SVG繪圖標記作爲一個字符串,並將其作爲原樣附加到HTML元素。問題是具體詢問如何將SVG元素添加到現有的繪圖中。現在,你可以在某些瀏覽器中編寫SVG元素的'innerHTML',但是[這個功能是新的,並且只在今年早些時候纔可用](http://stackoverflow.com/questions/23275112#comment45705022_23279658) 。現在在IE中添加一個元素到現有繪圖中的唯一方法是,通過'createElementNS()',在所有這些問題被詢問的瀏覽器中。 – gilly3 2015-07-09 19:03:51

8

首先,使用createElementNS,就像你在做什麼一樣。根據Mozilla documentation,createElement(沒有NS)會自動降低HTML文檔中的元素名稱。其次,不要相信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> 

我的問題可能有事情做與在Chrome破碎處理animateMotion的(Issue 13585)。

您的問題可能是相同的,或者可能是另一個問題,但請確保您沒有被元素檢查員愚弄。

+1

您對chromes inspect元素功能的評論保存了我的一天,謝謝 – ZPiDER 2013-10-15 18:01:02

5

我剛剛解決了類似的問題。 document.createElement(我假設document.createElementNS),當從一個HTML頁面調用時創建一個HTML節點(這裏case不重要),而不是一個XML節點。

在Chrome以下工作:

DOC = document.implementation.createDocument(NULL,NULL,NULL); doc.createElementNS(「http://www.w3。組織/ 2000/SVG」,‘textPath’);?

你會得到你大小寫混合節點