2010-08-16 17 views
17

Je veux créer des graphiques SVG en ligne en utilisant Javascript. Cependant, il semble que la fonction createElementNS applique une certaine normalisation et transforme toutes les balises en minuscules. C'est bien pour HTML mais pas pour XML/SVG. Le NS que j'ai utilisé est http://www.w3.org/2000/svg.JavaScript createElement et SVG

En particulier, j'ai des problèmes pour créer un élément. Comme il sera ajouté en tant que tel ne fonctionnera pas.

J'ai fait quelques recherches mais je n'ai pas encore trouvé de solution.

Est-ce que quelqu'un connaît une solution?

Merci beaucoup!

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

résultats dans

<textpath></textpath> 
+0

Comment trouvez-vous ce qui se passe Comment vider-vous l'élément créé dans le code XML Les noms de balises XML devrait Soyez sensible: http://ejohn.org/blog/nodename-case-sensitivity/ –

Répondre

27

je l'espère, l'exemple suivant vous aidera:

<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

Merci pour votre réponse, basée sur votre réponse et un exemple de svg text-to-path: [http://pmast.de/svg/ textToPath.svg] (http://pmast.de/svg/textToPath.svg) J'ai créé le document suivant: [http://pmast.de/svg/textToPath.html](http://pmast.de/ svg/textToPath.html) Bien que la source résultante semble identique et que la création des éléments suive votre exemple, mon document ne fonctionne pas ... Ai-je raté quelque chose? – pat

+0

Votre exemple m'a aidé à créer des éléments SVG à partir de JS. Toujours dû lire le document de spécification W3.org sur Core DOM. Les espaces de noms sont plutôt confus. Merci pour les conseils. – CyberFonic

+1

Est-ce que cela fonctionne pour les gens? Je viens d'obtenir une boîte grise sans aucun élément SVG. (Firefox et Chrome semblables) – schlingel

-4

la réponse donnée est trop vaste et pas vraiment utile pour moi et je trouve à beaucoup gênant ou simplement dire faux. Si je devais vous, je simplement ai sur l'élément en html tag dire:

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

et quand je dois créer élément ou ajouter de l'information je voudrais simplement faire:

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

J'espère que ce utile.

+0

Cette question concerne SVG, pas HTML. – gilly3

+0

@ gilly3 il a un point cependant - la réponse acceptée consiste à construire un élément SVG DOM fondamentalement à partir de zéro qui, tout en étant propre à savoir comment faire et techniquement la réponse la plus correcte, n'est pas entièrement pratique. Puisque la syntaxe SVG dans un fichier SVG est presque identique à la syntaxe de définition SVG dans le DOM (depuis la sous-chaîne 'svg'), il est beaucoup plus pratique de prendre un élément container comme span ou b et de définir son attribut innerHTML les données SVG brutes - le navigateur prend en charge le travail d'analyse et de construction dur pour vous de cette façon. Je dirais que c'est une réponse 'quick-fix' valide – CCJ

+1

C'est un cas d'utilisation assez spécifique - d'avoir tout le balisage de dessin SVG sous forme de chaîne, et l'ajouter tel quel à un élément HTML. La question concerne spécifiquement l'ajout d'un élément SVG à un dessin existant. Maintenant, aujourd'hui, vous pouvez écrire le 'innerHTML' d'un élément SVG dans certains navigateurs, mais [cette fonctionnalité est nouvelle, et n'a été disponible depuis plus tôt cette année] (http://stackoverflow.com/questions/23275112#comment45705022_23279658) . La seule façon d'ajouter un élément à un dessin existant dans IE aujourd'hui, et dans tous les navigateurs au moment où cette question a été posée, est via 'createElementNS()'. – gilly3

8

Tout d'abord, utilisez createElementNS, comme vous le faites. createElement (sans NS) automatiquement les noms des éléments en minuscules à l'intérieur des documents HTML, selon le Mozilla documentation.

Deuxièmement, ne faites pas confiance à la fonctionnalité "Inspecter élément" de Google Chrome ici. Il semble afficher chaque élément en minuscules, quel que soit le nœud actuel. Essayez ceci:

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

Votre problème peut être un problème sans rapport. Par exemple, ce code fonctionne bien dans Firefox, mais des ruptures dans 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> 

Ma question a probablement quelque chose à voir avec la manipulation cassée de animateMotion dans Chrome (Issue 13585).

Il se peut que votre problème soit identique ou qu'il s'agisse d'un autre problème, mais assurez-vous de ne pas vous laisser berner par l'inspecteur des éléments.

+1

votre commentaire à propos de chromes inspectent élément caractéristique sauvé ma journée, merci – ZPiDER

5

Je viens de résoudre un problème similaire. document.createElement (et j'assume document.createElementNS), lorsqu'il est appelé à partir d'une page HTML crée un nœud HTML (où cas n'a pas d'importance), pas un nœud xml.

Les ouvrages suivants dans Chrome:

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

vous obtiendrez votre nœud mixte cas