SVG становится черным при клонировании
я играл с clone()
функция из jQuery, когда я обнаружил странное поведение.
этот код воспроизводит проблему. Первый div содержит SVG. Две кнопки позволяют делать / отменять клон SVG во второй div. Если попробовать два раза, круг почернеет.
HTML-код
<div id="orgdiv">
<svg width="200" height="200" style="margin:0">
<linearGradient id="r" x1="0" y1="0" x2="1" y2="1">
<stop offset="0%" stop-color="#00ffff"></stop>
<stop offset="100%" stop-color="#ffff00"></stop>
</linearGradient>
<circle cx="100" cy="100" r="80" style="fill:url(#r)" />
</svg>
</div>
<input type="button" value="copy">
<input type="button" value="clear">
<div id="copydiv"></div>
JS
$('input[value="copy"]').click(function(){
$("#copydiv").html($("#orgdiv").clone());
});
$('input[value="clear"]').click(function(){
$("#copydiv").empty();
});
Примечание:
- клонирование с помощью jQuery или JavaScript приводит к той же ошибке.
3 ответов
у меня есть предчувствие, что это может быть потому, что вы клонируете linearGradient, у которого есть id
атрибут (который, конечно же, должен быть уникальным во всем документе.) Это может запутать процессор SVG.
моя теория, кажется, подтверждается изменением идентификатора по пути через клон:
$('input[value="copy"]').click(function () {
var clone = $("#orgdiv").clone();
// Change the ID of the clone, so we don't have duplicate IDs
clone.find("#r").attr('id', 'unique');
$("#copydiv").html(clone);
});
...что, похоже, предотвращает проблему. (В этом случае клон все еще получает градиент, даже если идентификатор его клонированного градиента изменился, потому что он поиск исходного градиента по его идентификатору.)
JSFiddle здесь:http://jsfiddle.net/2K4xv/2/
Я предполагаю, что то, что происходит "под капотом" в вашем случае, заключается в том, что процессор подбирает второй градиентный фильтрующий элемент, который вы создаете для использования с первым кругом, а затем теряет ссылку на него, когда он уничтожается вашим empty()
, таким образом, оставив вас с кругом, но без градиента. Именно поэтому это происходит только во второй раз through, вероятно, вплоть до деталей реализации взаимодействия SVG renderer с документом HTML5.
есть больше информации по этому вопросу в этот предыдущий вопрос.
Как только вы клонируете его, у вас есть два элемента с идентификатором "r", один в оригинале и один в Клоне. Все идентификаторы должны быть уникальными, поэтому документ больше не действителен.
@Matt Gibson представляет Хак: барабанить новые идентификаторы, а затем дублировать html с избыточным linearGradient
определения ссылка на оригинал linearGradient
.
к счастью, вам нужно это сделать;)
часть силы svg
теги - это их собственные сумасшедшие маленькие контейнеры. таким образом, вы можете ссылаться на материал извне из uri.
&поэтому, если вы занимаетесь клонированием, то вместо того, чтобы беспокоиться об идентификаторах, вы можете абстрагироваться от шаблон модели и повторно использовать его ad-infinitum:
$(document).ready(function(){
$('input[value="copy"]').click(function () {
$("#copydiv").append($(":first", "#orgdiv").clone());
});
$('input[value="clear"]').click(function () {
$("#copydiv").empty();
});
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<!-- ------------------- platonic horse ------------------------- -->
<div style="visibility:hidden; position:absolute; width:0">
<svg>
<g id="my-funky-svg-defs">
<defs>
<radialGradient id="gradient" cx="25%" cy="25%" r="100%" fx="40%" fy="40%">
<stop offset= "0%" stop-color="hsla(313, 80%, 80%, 1)"/>
<stop offset= "40%" stop-color="hsla(313, 100%, 65%, 1)"/>
<stop offset="110%" stop-color="hsla(313, 100%, 50%, 0.7)"/>
</radialGradient>
</defs>
<title>smarteee</title>
<circle class="face" cx="200" cy="200" r="195" fill="url(#gradient)" />
<ellipse class="eye eye-left" cx="140" cy="150" rx="10" ry="40" fill="#131313"/>
<ellipse class="eye eye-right" cx="260" cy="150" rx="10" ry="40" fill="#131313"/>
<path class="smile" d="M120,280 Q200,330 280,280" stroke-width="10" stroke="#131313" fill="none" stroke-linecap="round"/>
</g>
</svg>
</div>
<!-- ---------------------- prototype ----------------------- ---- -->
proto
<input type="button" value="copy"/>
<hr/>
<div id="orgdiv">
<svg width="20px" height="20px" viewBox="0 0 400 400" style="margin:20px;">
<use xlink:href="#my-funky-svg-defs"></use>
</svg>
</div>
<!-- ------------------------- clones ----------------------- ---- -->
clones
<input type="button" value="clear"/>
<hr/>
<div id="copydiv"></div>