accepted answer 显示方式过于复杂。正如 Forresto 在 his answer 中声称的那样,“它似乎确实将它们添加到 DOM 资源管理器中,而不是在屏幕上”,原因是 html 和 svg 的命名空间不同。
最简单的解决方法是“刷新”整个 svg。附加圆圈(或其他元素)后,使用:
$("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('<defs><marker></marker><mask></mask></defs>'); 就像你在 jQuery 中所做的那样。
- 在元素被添加并使用
$("#cont").html($("#cont").html());在屏幕上可见之后,它们的属性可以使用jQuery进行编辑。
编辑:
上述技术仅适用于“硬编码”或 DOM 操作(= document.createElementNS 等)SVG。如果 Raphael 用于创建元素,(根据我的测试)如果使用 $("#cont").html($("#cont").html());,Raphael 对象和 SVG DOM 之间的链接将被破坏。解决方法是根本不使用$("#cont").html($("#cont").html());,而是使用虚拟 SVG 文档。
这个虚拟 SVG 首先是 SVG 文档的文本表示,并且只包含需要的元素。如果我们想要例如。要将过滤器元素添加到 Raphael 文档,虚拟对象可能类似于 <svg id="dummy" style="display:none"><defs><filter><!-- Filter definitons --></filter></defs></svg>。文本表示首先使用 jQuery 的 $("body").append() 方法转换为 DOM。当 (filter) 元素在 DOM 中时,可以使用标准 jQuery 方法对其进行查询,并将其附加到由 Raphael 创建的主 SVG 文档中。
为什么需要这个假人?为什么不对 Raphael 创建的文档严格添加过滤器元素?如果您尝试使用例如。 $("svg").append("<circle ... />"),它被创建为 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。
(我(还)不知道,为什么 $("#cont").html($("#cont").html()); 在使用 Raphael 时不起作用。这将是非常简短的 hack。)