El accepted answer muestra demasiado complicado. Como afirma Forresto en his answer, "parece agregarlos en el explorador de DOM, pero no en la pantalla" y el motivo de esto son diferentes espacios de nombres para html y svg.
La solución más fácil es "actualizar" toda svg. Después de agregar el círculo (u otros elementos), utilice esto:
$("body").html($("body").html());
Esto lo hace el truco. El círculo está en la pantalla.
O si lo desea, utilice un contenedor div:
$("#cont").html($("#cont").html());
Y envolver su SVG dentro de contenedor 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>
El ejemplo funcional:
http://jsbin.com/ejifab/1/edit
Las ventajas de esta técnica:
- puede editar svg existente (que ya está en DOM), por ej. creado usando Raphael o como en su ejemplo "codificado" sin scripting.
- puede agregar estructuras de elementos complejos como cadenas, por ejemplo.
$('svg').prepend('<defs><marker></marker><mask></mask></defs>');
como lo haces en jQuery.
- después de que los elementos se anexen y se hagan visibles en la pantalla usando
$("#cont").html($("#cont").html());
sus atributos se pueden editar usando jQuery.
EDIT:
La técnica anterior funciona con "codificado" o DOM manipulado (= document.createElementNS etc.) SVG solamente. Si Raphael se usa para crear elementos, (de acuerdo con mis pruebas) el enlace entre los objetos de Rafael y SVG DOM se rompe si se usa $("#cont").html($("#cont").html());
. La solución a esto no es utilizar $("#cont").html($("#cont").html());
en absoluto y en lugar de usar el documento SVG ficticio.
Este SVG ficticio es primero una representación textual del documento SVG y contiene solo los elementos que se necesitan. Si queremos, por ej. para agregar un elemento de filtro al documento de Raphael, el maniquí podría ser algo así como <svg id="dummy" style="display:none"><defs><filter><!-- Filter definitons --></filter></defs></svg>
. La representación textual se convierte primero a DOM utilizando el método jQuery's $ ("body"). Append(). Y cuando el elemento (filtro) está en DOM, se puede consultar utilizando los métodos jQuery estándar y anexar al documento SVG principal creado por Raphael.
¿Por qué se necesita este maniquí? ¿Por qué no agregar un elemento de filtro estrictamente al documento creado por Raphael? Si lo intentas usando, por ej. $("svg").append("<circle ... />")
, se crea como elemento html y no hay nada en la pantalla como se describe en las respuestas. Pero si se adjunta el documento SVG completo, el navegador maneja automáticamente la conversión del espacio de nombres de todos los elementos en el documento SVG.
Un ejemplo iluminar la 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)");
demostración de trabajo completa de esta técnica es aquí: http://jsbin.com/ilinan/1/edit.
(I tiene (todavía) ni idea, ¿por qué $("#cont").html($("#cont").html());
no funciona cuando se utiliza Raphael. Sería muy corto truco.)
Qué navegador? – Topera