W Zaakceptowanych odpowiedź pokazuje zbyt skomplikowany sposób. Jak twierdzi Forresto w swojej odpowiedzi „ wydaje się, że dodaje je w eksploratorze DOM, ale nie na ekranie ”, a przyczyną tego są różne przestrzenie nazw dla html i svg.
Najłatwiejszym obejściem jest „odświeżenie” całego pliku svg. Po dołączeniu kręgu (lub innych elementów) użyj tego:
$("body").html($("body").html());
To załatwia sprawę. Krąg jest na ekranie.
Lub jeśli chcesz, użyj div kontenera:
$("#cont").html($("#cont").html());
I owinąć swój plik SVG wewnątrz div pojemnika:
<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>
Przykład funkcjonalny:
http://jsbin.com/ejifab/1/edit
Zalety tej techniki:
- możesz edytować istniejący plik svg (który jest już w DOM), np. utworzony przy użyciu Raphaela lub jak w twoim przykładzie „na stałe” bez skryptów.
- możesz dodawać złożone struktury elementów jako ciągi znaków, np.
$('svg').prepend('<defs><marker></marker><mask></mask></defs>');
jak ty w jQuery.
- po dodaniu elementów i wyświetleniu
$("#cont").html($("#cont").html());
ich na ekranie za pomocą ich atrybutów można je edytować za pomocą jQuery.
EDYTOWAĆ:
Powyższa technika działa tylko z SVG „zakodowanym na stałe” lub DOM (= document.createElementNS itp.). Jeśli Raphael jest używany do tworzenia elementów, (zgodnie z moimi testami) połączenie między obiektami Raphaela i SVG DOM zostanie przerwane, jeśli $("#cont").html($("#cont").html());
zostanie użyte. Obejściem tego problemu jest w ogóle nieużywanie, $("#cont").html($("#cont").html());
a zamiast tego używanie fałszywego dokumentu SVG.
Ten manekin SVG jest najpierw tekstową reprezentacją dokumentu SVG i zawiera tylko potrzebne elementy. Jeśli chcemy np. aby dodać element filtrujący do dokumentu Raphaela, manekin może być podobny <svg id="dummy" style="display:none"><defs><filter><!-- Filter definitons --></filter></defs></svg>
. Reprezentacja tekstowa jest najpierw konwertowana na DOM za pomocą metody $ („body”). Append () jQuery'ego. A gdy element (filter) znajduje się w DOM, można go odpytywać przy użyciu standardowych metod jQuery i dołączać do głównego dokumentu SVG, który jest tworzony przez Raphaela.
Dlaczego ten manekin jest potrzebny? Dlaczego nie dodać elementu filtrującego ściśle do dokumentu utworzonego przez Raphaela? Jeśli spróbujesz użyć np. $("svg").append("<circle ... />")
, jest tworzony jako element HTML i nic nie jest wyświetlane na ekranie, jak opisano w odpowiedziach. Ale jeśli dołączony jest cały dokument SVG, przeglądarka automatycznie obsługuje konwersję przestrzeni nazw wszystkich elementów w dokumencie SVG.
Przykład oświeca technikę:
// 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)");
Pełna działająca wersja demonstracyjna tej techniki znajduje się tutaj: http://jsbin.com/ilinan/1/edit .
(Nie mam (jeszcze) pojęcia, dlaczego $("#cont").html($("#cont").html());
nie działa przy użyciu Rafaela. Byłby to bardzo krótki hack.)
RMB
>edit as html
na znaczniku html i naciśniesz, wpisz wszystko, co się wyświetla (ale wszystkie detektory zdarzeń znikają). Po przeczytaniu tej odpowiedzi zmieniłem wywołania createElement na createElementNS i teraz wszystko działa!