Когда вы передаете строку разметки в $
нее, она анализируется как HTML с использованием innerHTML
свойства браузера в <div>
(или другом подходящем контейнере для особых случаев, например <tr>
). innerHTML
не может проанализировать SVG или другой контент, не относящийся к HTML, и даже если бы он мог, он не смог бы определить, что <circle>
должно быть в пространстве имен SVG.
innerHTML
недоступно в SVGElement - это свойство только HTMLElement. В настоящее время нет ни innerSVG
свойства, ни другого способа (*) для анализа содержимого в SVGElement. По этой причине вам следует использовать методы в стиле DOM. jQuery не дает вам простой доступ к методам пространства имен, необходимым для создания элементов SVG. Действительно, jQuery вообще не предназначен для использования с SVG, и многие операции могут завершиться неудачно.
HTML5 обещает позволить вам использовать в будущем <svg>
без xmlns
простого HTML ( text/html
) документа. Но это всего лишь хакер синтаксического анализа (**), содержимое SVG по-прежнему будет SVGElement в пространстве имен SVG, а не HTMLElements, поэтому вы не сможете использовать его, innerHTML
даже если они выглядят как часть HTML-документа.
Тем не менее, в современных браузерах вы должны использовать X HTML (должным образом application/xhtml+xml
; сохраните с расширением .xhtml для локального тестирования), чтобы заставить SVG работать вообще. (Это в любом случае имеет смысл; SVG является стандартом, основанным на XML.) Это означает, что вам нужно экранировать <
символы внутри вашего блока скрипта (или заключать в раздел CDATA) и включать xmlns
декларацию XHTML . пример:
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml"><head>
</head><body>
<svg id="s" xmlns="http://www.w3.org/2000/svg"/>
<script type="text/javascript">
function makeSVG(tag, attrs) {
var el= document.createElementNS('http://www.w3.org/2000/svg', tag);
for (var k in attrs)
el.setAttribute(k, attrs[k]);
return el;
}
var circle= makeSVG('circle', {cx: 100, cy: 50, r:40, stroke: 'black', 'stroke-width': 2, fill: 'red'});
document.getElementById('s').appendChild(circle);
circle.onmousedown= function() {
alert('hello');
};
</script>
</body></html>
*: хорошо, есть parseWithContext DOM Level 3 LS , но поддержка браузера очень плохая. Отредактируйте, чтобы добавить: однако, хотя вы не можете внедрить разметку в SVGElement, вы можете добавить новый SVGElement в HTMLElement, используя innerHTML
, а затем перенести его в нужную цель. Это, вероятно, будет немного медленнее, хотя:
<script type="text/javascript"><![CDATA[
function parseSVG(s) {
var div= document.createElementNS('http://www.w3.org/1999/xhtml', 'div');
div.innerHTML= '<svg xmlns="http://www.w3.org/2000/svg">'+s+'</svg>';
var frag= document.createDocumentFragment();
while (div.firstChild.firstChild)
frag.appendChild(div.firstChild.firstChild);
return frag;
}
document.getElementById('s').appendChild(parseSVG(
'<circle cx="100" cy="50" r="40" stroke="black" stroke-width="2" fill="red" onmousedown="alert(\'hello\');"/>'
));
]]></script>
**: я ненавижу то, как авторы HTML5, похоже, напуганы XML и полны решимости использовать особенности, основанные на XML, в сложном беспорядке HTML. XHTML решил эти проблемы много лет назад.
RMB
>edit as html
в теге html и нажать клавишу ввода, все отображается (но все прослушиватели событий исчезают). После прочтения этого ответа я изменил свои вызовы createElement на createElementNS, и теперь все работает!d3.select('body').append('svg').attr('width','100%');
$.parseXML
.В ответ принятые шоу слишком сложным способом. Как утверждает Форресто в своем ответе , « он, кажется, добавляет их в проводнике DOM, но не на экране », и причина этого - разные пространства имен для html и svg.
Самый простой обходной путь - «обновить» весь SVG. После добавления круга (или других элементов) используйте это:
Это делает трюк. Круг на экране.
Или, если хотите, используйте контейнер div:
И оберните свой svg внутри контейнера div:
Функциональный пример:
http://jsbin.com/ejifab/1/edit
Преимущества этой техники:
$('svg').prepend('<defs><marker></marker><mask></mask></defs>');
как вы делаете в jQuery.$("#cont").html($("#cont").html());
их атрибуты можно редактировать с помощью jQuery.РЕДАКТИРОВАТЬ:
Вышеприведенный метод работает только с SVG «жестко запрограммированным» или DOM-манипулированием (= document.createElementNS и т. Д.). Если для создания элементов используется Raphael, то (согласно моим тестам) связь между объектами Raphael и SVG DOM нарушается, если
$("#cont").html($("#cont").html());
используется. Обходной путь к этому не должен использовать$("#cont").html($("#cont").html());
вообще и вместо этого использовать фиктивный документ SVG.Этот фиктивный SVG является вначале текстовым представлением документа SVG и содержит только необходимые элементы. Если мы хотим, например. чтобы добавить элемент фильтра к документу Рафаэля, пустышка может выглядеть примерно так
<svg id="dummy" style="display:none"><defs><filter><!-- Filter definitons --></filter></defs></svg>
. Текстовое представление сначала преобразуется в DOM с помощью метода jQuery $ ("body"). Append (). А когда элемент (filter) находится в DOM, его можно запросить с помощью стандартных методов jQuery и добавить к основному документу SVG, который создан Raphael.Зачем этот манекен нужен? Почему бы не добавить элемент фильтра строго в документ, созданный Рафаэлем? Если вы попробуете, используя, например.
$("svg").append("<circle ... />")
, он создается как элемент HTML, и на экране ничего не отображается, как описано в ответах. Но если весь документ SVG добавляется, то браузер автоматически обрабатывает преобразование пространства имен всех элементов в документе SVG.Пример просветления техники:
Полная рабочая демонстрация этой техники находится здесь: http://jsbin.com/ilinan/1/edit .
(Я не знаю (пока), почему
$("#cont").html($("#cont").html());
не работает при использовании Рафаэля. Это был бы очень короткий взлом.)источник
$("#cont").html($("#cont").html());
отлично работал в Chrome, но не работал в IE 11 для меня.Все более популярная библиотека D3 прекрасно справляется со сложностями добавления / манипулирования svg. Вы можете рассмотреть возможность его использования в отличие от хаков jQuery, упомянутых здесь.
HTML
Javascript
источник
JQuery не может добавлять элементы
<svg>
(кажется, что они добавляются в проводнике DOM, но не на экране).Одним из обходных путей является добавление
<svg>
со всеми необходимыми элементами на страницу, а затем изменение атрибутов элементов с помощью.attr()
.http://jsfiddle.net/8FBjb/1/
источник
<circle>
или других элементов, индивидуально использующих сложные и медленные DOM-методы (например,createDocumentFragment()
илиcreateElementNS()
), добавьте весь документ SVG в контейнер. Вместо $ ('body') это может быть также $ ('div'). И после этого документ svg находится в DOM и может быть запрошен обычным способом с помощью, например. $ ( 'с'). атр ( 'заливка', 'красный').Я не видел, чтобы кто-то упоминал этот метод, но
document.createElementNS()
он полезен в этом случае.Вы можете создавать элементы, используя ванильный Javascript как обычные узлы DOM с правильным пространством имен, а затем jQuery-ify их оттуда. Вот так:
Единственным недостатком является то, что вы должны создавать каждый элемент SVG с правильным пространством имен индивидуально, иначе он не будет работать.
источник
Нашел простой способ, который работает со всеми браузерами (Chrome 49, Edge 25, Firefox 44, IE11, Safari 5 [Win], Safari 8 (MacOS)):
источник
Я могу видеть круг в Firefox, делая 2 вещи:
1) Переименование файла из html в xhtml
2) Изменить скрипт на
источник
Основано на ответе @ chris-dolphin, но с использованием вспомогательной функции:
источник
$svg.append($s('<circle cx="100" cy="50" r="40" stroke="black" stroke-width="2" fill="red"/>'));
Если вам нужно добавить строку SVG и вы добавили правильное пространство имен, вы можете проанализировать строку как XML и добавить к родителю.
источник
Принятый ответ Bobince - это короткое, портативное решение. Если вам нужно не только добавить SVG, но и манипулировать им, вы можете попробовать библиотеку JavaScript «Pablo» (я написал). Это будет знакомо пользователям jQuery.
Ваш пример кода будет выглядеть так:
Вы также можете создавать элементы SVG на лету, не указывая разметку:
источник
Я хотел бы предположить, что может быть лучше использовать ajax и загрузить элемент svg с другой страницы.
Где href - это местоположение страницы с svg. Таким образом, вы можете избежать любых нервных эффектов, которые могут возникнуть при замене HTML-контента. Также не забудьте развернуть svg после загрузки:
источник
Это работает для меня сегодня с FF 57:
ПРОИЗВОДИТ:
источник
$(this).clone()
клонирует элемент SVG (и это дети, если он есть). Смотри мимо использованияtext()
. Я беру один tspan, в котором было "Your New", и в итоге получился два tspan, один с "Your" в нем (черный) и один с "New in it" (синий с проходом через строку). Боже, уменьшено с 0 голосов до -1 :-(источник
Гораздо более простой способ - просто сгенерировать SVG в строку, создать HTML-элемент-оболочку и вставить строку svg в HTML-элемент, используя
$("#wrapperElement").html(svgString)
. Это прекрасно работает в Chrome и Firefox.источник