假设:

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

为什么我什么都看不到?


当前回答

我还没见过有人提到这个方法,但是document.createElementNS()在这个实例中很有帮助。

您可以使用普通Javascript将元素创建为具有正确名称空间的普通DOM节点,然后从那里对它们进行jquery化。像这样:

var svg = document.createElementNS('http://www.w3.org/2000/svg', 'svg'),
    circle = document.createElementNS('http://www.w3.org/2000/svg', 'circle');

var $circle = $(circle).attr({ //All your attributes });

$(svg).append($circle);

唯一的缺点是您必须使用正确的名称空间单独创建每个SVG元素,否则它将无法工作。

其他回答

公认的答案显得太复杂了。正如Forresto在他的回答中所声称的那样,“它似乎是在DOM资源管理器中添加它们,而不是在屏幕上”,其原因是html和svg的名称空间不同。

最简单的解决方法是“刷新”整个svg。在添加circle(或其他元素)后,使用以下语句:

$("body").html($("body").html());

这很管用。这个圆在屏幕上。

或者,如果你愿意,使用容器div:

$("#cont").html($("#cont").html());

然后将svg包装到容器div中:

<div id="cont">
    <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>
</div>

函数示例: http://jsbin.com/ejifab/1/edit

该技术的优点:

您可以编辑现有的svg(已经在DOM中),例如。创建使用Raphael或像在你的例子中“硬编码”没有脚本。 你可以添加复杂的元素结构如字符串。$ (svg) .prepend(“< def > <标记> < / >标记<面具> < /面具> < / def >”);就像在jQuery中一样。 在添加元素并在屏幕上显示后,使用$("#cont").html($("#cont").html());它们的属性可以使用jQuery编辑。


编辑:

上述技术适用于“硬编码”或DOM操纵(= document。仅支持SVG。如果Raphael用于创建元素,(根据我的测试)Raphael对象和SVG DOM之间的链接被破坏,如果$(“#cont”).html($(“#cont”).html());使用。解决方法不是使用$("#cont").html($("#cont").html());而不是使用虚拟SVG文档。

This dummy SVG is first a textual representation of SVG document and contains only elements that are needed. If we want eg. to add a filter element to Raphael document, the dummy could be something like <svg id="dummy" style="display:none"><defs><filter><!-- Filter definitons --></filter></defs></svg>. The textual representation is first converted to DOM using jQuery's $("body").append() method. And when the (filter) element is in DOM, it can be queried using standard jQuery methods and appended to the main SVG document which is created by Raphael.

为什么需要这个假人?为什么不添加一个过滤器元素严格拉斐尔创建的文件?如果你试着用eg。美元(svg)。追加(“<圆…/>"),它被创建为HTML元素,屏幕上没有答案中描述的内容。但是如果附加了整个SVG文档,那么浏览器将自动处理SVG文档中所有元素的名称空间转换。

下面是一个例子:

// Add Raphael SVG document to container element
var p = Raphael("cont", 200, 200);
// Add id for easy access
$(p.canvas).attr("id","p");
// Textual representation of element(s) to be added
var f = '<filter id="myfilter"><!-- filter definitions --></filter>';

// Create dummy svg with filter definition 
$("body").append('<svg id="dummy" style="display:none"><defs>' + f + '</defs></svg>');
// Append filter definition to Raphael created svg
$("#p defs").append($("#dummy filter"));
// Remove dummy
$("#dummy").remove();

// Now we can create Raphael objects and add filters to them:
var r = p.rect(10,10,100,100);
$(r.node).attr("filter","url(#myfilter)");

该技术的完整演示在这里:http://jsbin.com/ilinan/1/edit。

(我有(还)不知道,为什么美元(“#合同”). html($(" #合同”). html ());当使用拉斐尔时不工作。这将是非常短的hack。)

越来越流行的D3库很好地处理了附加/操作svg的奇怪问题。您可能会考虑使用它,而不是这里提到的jQuery hacks。

HTML

<svg xmlns="http://www.w3.org/2000/svg"></svg>

Javascript

var circle = d3.select("svg").append("circle")
    .attr("r", "10")
    .attr("style", "fill:white;stroke:black;stroke-width:5");

这是我今天对FF 57的工作:

function () {
    // JQuery, today, doesn't play well with adding SVG elements - tricks required
    $(selector_to_node_in_svg_doc).parent().prepend($(this).clone().text("Your"));
    $(selector_to_node_in_svg_doc).text("New").attr("x", "340").text("New")
        .attr('stroke', 'blue').attr("style", "text-decoration: line-through");
}

使:

我建议最好使用ajax并从另一个页面加载svg元素。

$('.container').load(href + ' .svg_element');

其中href是带有svg. xml的页面的位置。通过这种方式,您可以避免替换html内容时可能发生的任何紧张影响。另外,不要忘记在svg加载后打开它:

$('.svg_element').unwrap();

我还没见过有人提到这个方法,但是document.createElementNS()在这个实例中很有帮助。

您可以使用普通Javascript将元素创建为具有正确名称空间的普通DOM节点,然后从那里对它们进行jquery化。像这样:

var svg = document.createElementNS('http://www.w3.org/2000/svg', 'svg'),
    circle = document.createElementNS('http://www.w3.org/2000/svg', 'circle');

var $circle = $(circle).attr({ //All your attributes });

$(svg).append($circle);

唯一的缺点是您必须使用正确的名称空间单独创建每个SVG元素,否则它将无法工作。