A resposta aceita mostra uma maneira muito complicada. Como Forresto afirma em sua resposta , " parece adicioná-los no explorador DOM, mas não na tela " e a razão para isso são diferentes namespaces para html e svg.
A solução mais fácil é "atualizar" svg inteiro. Após anexar o círculo (ou outros elementos), use o seguinte:
$("body").html($("body").html());
Isso faz o truque. O círculo está na tela.
Ou, se desejar, use um contêiner div:
$("#cont").html($("#cont").html());
E envolva seu svg dentro do container 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>
O exemplo funcional:
http://jsbin.com/ejifab/1/edit
As vantagens desta técnica:
- você pode editar svg existente (que já está no DOM), por exemplo. criado usando Raphael ou como no seu exemplo "codificado" sem script.
- você pode adicionar estruturas de elementos complexos como strings, por exemplo.
$('svg').prepend('<defs><marker></marker><mask></mask></defs>');
como você faz no jQuery.
- depois que os elementos são anexados e tornados visíveis na tela usando
$("#cont").html($("#cont").html());
seus atributos, podem ser editados usando o jQuery.
EDITAR:
A técnica acima funciona apenas com SVG "codificado" ou manipulado pelo DOM (= document.createElementNS etc.). Se o Raphael for usado para criar elementos, (de acordo com meus testes), a vinculação entre objetos do Raphael e o SVG DOM será interrompida se $("#cont").html($("#cont").html());
for usada. A solução alternativa para isso é não usar $("#cont").html($("#cont").html());
nada e, em vez disso, usar documento SVG fictício.
Este SVG fictício é primeiro uma representação textual do documento SVG e contém apenas os elementos necessários. Se queremos, por exemplo. Para adicionar um elemento de filtro ao documento do Raphael, o manequim pode ser algo parecido <svg id="dummy" style="display:none"><defs><filter><!-- Filter definitons --></filter></defs></svg>
. A representação textual é primeiro convertida para DOM usando o método $ ("body"). Append () do jQuery. E quando o elemento (filter) está no DOM, ele pode ser consultado usando métodos jQuery padrão e anexado ao documento SVG principal criado por Raphael.
Por que esse manequim é necessário? Por que não adicionar um elemento de filtro estritamente ao documento criado pelo Rafael? Se você tentar usando, por exemplo. $("svg").append("<circle ... />")
, ele é criado como elemento html e nada está na tela, conforme descrito nas respostas. Mas se todo o documento SVG for anexado, o navegador manipulará automaticamente a conversão de namespace de todos os elementos no documento SVG.
Um exemplo esclarece a técnica:
// 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)");
A demonstração completa dessa técnica está disponível em: http://jsbin.com/ilinan/1/edit .
(Ainda não faço ideia, por $("#cont").html($("#cont").html());
que não funciona ao usar o Raphael. Seria um corte muito curto.)
RMB
>edit as html
na tag html e pressionar enter, tudo será exibido (mas todos os ouvintes de eventos desaparecerão). Depois de ler esta resposta, mudei minhas chamadas createElement para createElementNS e agora tudo funciona!