假设:

<html>
<head>
 <script type="text/javascript" src="jquery.js"></script>
 <script type="text/javascript">
 $(document).ready(function(){
  $("svg").append('<circle cx="100" cy="50" r="40" stroke="black" stroke-width="2" fill="red"/>');
 });
 </script>
</head>
<body>
 <svg xmlns:svg="http://www.w3.org/2000/svg" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 200 100" width="200px" height="100px">
 </svg>
</body>

为什么我什么都看不到?


当前回答

我为此做了一个小函数。对于jQuery的追加方法,问题是需要为SVG指定命名空间,即“http://www.w3.org/2000/svg”更多

如果我准备它为appendmethod呢?在这种情况下,你只需要提供一些参数:

tagName:它可以是每一个SVG元素,如矩形,圆,文本,g等。

text:如果您正在使用类似text tagname的东西,则需要指定text

和SVG元素的其他已知属性。

因此,我要做的是定义一个名为createSvgElem()的函数,它在内部使用document.createElementNS()。

这里有一个例子:

$("svg").append(
   createSvgElem({tagName: "text", x: 10, y: 10, text: "ABC", style: "fill: red"})
)

这是函数:

   function createSvgElem(options){
        var settings = $.extend({
            }, options);

        if(!$.isEmptyObject(settings.tagName)){
            var el = document.createElementNS('http://www.w3.org/2000/svg', settings.tagName);
            for (var k in settings)
                if(k != "tagName" && k != "text" && settings[k] != "")//If attribute has value
                    el.setAttribute(k, settings[k]);

            if ("text" in settings)
                el.textContent = settings.text; //el.innerText; For IE
            return el;
        }
    }

你可以自己试试:

//Definition: function createSvgElem(options){ var settings = $.extend({ }, options); if(!$.isEmptyObject(settings.tagName)){ var el = document.createElementNS('http://www.w3.org/2000/svg', settings.tagName); for (var k in settings) if(k != "tagName" && k != "text" && settings[k] != "")//If attribute has value el.setAttribute(k, settings[k]); if ("text" in settings) el.textContent = settings.text; //el.innerText; For IE return el; } } //Usage: $(function(){ $("#svg-elem").append( createSvgElem({tagName: "rect", width: 130, height: 500, style: "fill: #000000a3;"}) ) $("#svg-elem").append( createSvgElem({tagName: "text", x: 30, y: 30, text: "ABCD", style: "fill: red"}) ) }) <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script> <svg id="svg-elem" width="200" height="200"> </svg>

其他回答

 var svg; // if you have variable declared and not assigned value.
 // then you make a mistake by appending elements to that before creating element    
 svg.appendChild(document.createElement("g"));
 // at some point you assign to svg
 svg = document.createElementNS('http://www.w3.org/2000/svg', "svg")
 // then you put it in DOM
 document.getElementById("myDiv").appendChild(svg)
 // it wont render unless you manually change myDiv DOM with DevTools

// to fix assign before you append
var svg = createElement("svg", [
    ["version", "1.2"],
    ["xmlns:xlink", "http://www.w3.org/1999/xlink"],
    ["aria-labelledby", "title"],
    ["role", "img"],
    ["class", "graph"]
]);
function createElement(tag, attributeArr) {
      // .createElementNS  NS is must! Does not draw without
      let elem = document.createElementNS('http://www.w3.org/2000/svg', tag);             
      attributeArr.forEach(element => elem.setAttribute(element[0], element[1]));
      return elem;
}
// extra: <circle> for example requires attributes to render. Check if missing.

我可以看到圈在firefox,做2件事:

1)将文件从html重命名为xhtml

2)更改脚本为

<script type="text/javascript">
$(document).ready(function(){
    var obj = document.createElementNS("http://www.w3.org/2000/svg", "circle");
    obj.setAttributeNS(null, "cx", 100);
    obj.setAttributeNS(null, "cy", 50);
    obj.setAttributeNS(null, "r",  40);
    obj.setAttributeNS(null, "stroke", "black");
    obj.setAttributeNS(null, "stroke-width", 2);
    obj.setAttributeNS(null, "fill", "red");
    $("svg")[0].appendChild(obj);
});
</script>

发现了一个简单的方法,适用于我所有的浏览器(Chrome 49, Edge 25, Firefox 44, IE11, Safari 5 [Win], Safari 8 (MacOS)):

// Clean svg content (if you want to update the svg's objects) // Note : .html('') doesn't works for svg in some browsers $('#svgObject').empty(); // add some objects $('#svgObject').append('<polygon class="svgStyle" points="10,10 50,10 50,50 10,50 10,10" />'); $('#svgObject').append('<circle class="svgStyle" cx="100" cy="30" r="25"/>'); // Magic happens here: refresh DOM (you must refresh svg's parent for Edge/IE and Safari) $('#svgContainer').html($('#svgContainer').html()); .svgStyle { fill:cornflowerblue; fill-opacity:0.2; stroke-width:2; stroke-dasharray:5,5; stroke:black; } <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> <div id="svgContainer"> <svg id="svgObject" height="100" width="200"></svg> </div> <span>It works if two shapes (one square and one circle) are displayed above.</span>

当您将标记字符串传递给$时,它将使用浏览器的innerHTML属性在<div>(或其他适合特殊情况的容器,如<tr>)上被解析为HTML。innerHTML不能解析SVG或其他非html内容,即使它可以,它也不能告诉<circle>应该在SVG名称空间中。

innerHTML在svgelement上是不可用的,它只是HTMLElement的一个属性。目前也没有innerSVG属性或其他方法(*)来将内容解析为SVGElement。出于这个原因,您应该使用dom风格的方法。jQuery不能让您轻松访问创建SVG元素所需的名称空间方法。实际上,jQuery根本不是为SVG设计的,许多操作可能会失败。

HTML5承诺让您在未来使用<svg>而无需在纯HTML(文本/ HTML)文档中使用xmlns。但这只是一个解析器hack(**), SVG内容仍然是SVG名称空间中的SVGElements,而不是HTMLElements,因此您将无法使用innerHTML,即使它们看起来像HTML文档的一部分。

然而,对于今天的浏览器,您必须使用XHTML(适当地作为application/ XHTML +xml;保存为本地测试的.xhtml文件扩展名)以使SVG能够正常工作。(这是有道理的;SVG是一种适当的基于xml的标准。)这意味着您必须转义脚本块中的<符号(或包含在CDATA部分中),并包括XHTML xmlns声明。例子:

<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml"><head>
</head><body>
    <svg id="s" xmlns="http://www.w3.org/2000/svg"/>
    <script type="text/javascript">
        function makeSVG(tag, attrs) {
            var el= document.createElementNS('http://www.w3.org/2000/svg', tag);
            for (var k in attrs)
                el.setAttribute(k, attrs[k]);
            return el;
        }

        var circle= makeSVG('circle', {cx: 100, cy: 50, r:40, stroke: 'black', 'stroke-width': 2, fill: 'red'});
        document.getElementById('s').appendChild(circle);
        circle.onmousedown= function() {
            alert('hello');
        };
    </script>
</body></html>

*:嗯,有DOM Level 3 LS的parseWithContext,但是浏览器的支持很差。编辑添加:然而,虽然你不能将标记注入到SVGElement中,你可以使用innerHTML将一个新的SVGElement注入到HTMLElement中,然后将它传输到所需的目标。不过它可能会慢一点:

<script type="text/javascript"><![CDATA[
    function parseSVG(s) {
        var div= document.createElementNS('http://www.w3.org/1999/xhtml', 'div');
        div.innerHTML= '<svg xmlns="http://www.w3.org/2000/svg">'+s+'</svg>';
        var frag= document.createDocumentFragment();
        while (div.firstChild.firstChild)
            frag.appendChild(div.firstChild.firstChild);
        return frag;
    }

    document.getElementById('s').appendChild(parseSVG(
        '<circle cx="100" cy="50" r="40" stroke="black" stroke-width="2" fill="red" onmousedown="alert(\'hello\');"/>'
    ));
]]></script>

**:我讨厌HTML5的作者似乎害怕XML,并决心将基于XML的功能硬塞进混乱的HTML中。XHTML几年前就解决了这些问题。

我为此做了一个小函数。对于jQuery的追加方法,问题是需要为SVG指定命名空间,即“http://www.w3.org/2000/svg”更多

如果我准备它为appendmethod呢?在这种情况下,你只需要提供一些参数:

tagName:它可以是每一个SVG元素,如矩形,圆,文本,g等。

text:如果您正在使用类似text tagname的东西,则需要指定text

和SVG元素的其他已知属性。

因此,我要做的是定义一个名为createSvgElem()的函数,它在内部使用document.createElementNS()。

这里有一个例子:

$("svg").append(
   createSvgElem({tagName: "text", x: 10, y: 10, text: "ABC", style: "fill: red"})
)

这是函数:

   function createSvgElem(options){
        var settings = $.extend({
            }, options);

        if(!$.isEmptyObject(settings.tagName)){
            var el = document.createElementNS('http://www.w3.org/2000/svg', settings.tagName);
            for (var k in settings)
                if(k != "tagName" && k != "text" && settings[k] != "")//If attribute has value
                    el.setAttribute(k, settings[k]);

            if ("text" in settings)
                el.textContent = settings.text; //el.innerText; For IE
            return el;
        }
    }

你可以自己试试:

//Definition: function createSvgElem(options){ var settings = $.extend({ }, options); if(!$.isEmptyObject(settings.tagName)){ var el = document.createElementNS('http://www.w3.org/2000/svg', settings.tagName); for (var k in settings) if(k != "tagName" && k != "text" && settings[k] != "")//If attribute has value el.setAttribute(k, settings[k]); if ("text" in settings) el.textContent = settings.text; //el.innerText; For IE return el; } } //Usage: $(function(){ $("#svg-elem").append( createSvgElem({tagName: "rect", width: 130, height: 500, style: "fill: #000000a3;"}) ) $("#svg-elem").append( createSvgElem({tagName: "text", x: 30, y: 30, text: "ABCD", style: "fill: red"}) ) }) <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script> <svg id="svg-elem" width="200" height="200"> </svg>