克隆时SVG变黑

Sté*_*ert 6 html javascript jquery svg clone

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>
Run Code Online (Sandbox Code Playgroud)

JS

$('input[value="copy"]').click(function(){
    $("#copydiv").html($("#orgdiv").clone());
});

$('input[value="clear"]').click(function(){
    $("#copydiv").empty();
});
Run Code Online (Sandbox Code Playgroud)

jsFiddle here

注意:

  • 用jQuery或Javascript克隆会导致同样的错误.

Mat*_*son 7

我有预感,因为你正在克隆linearGradient,它有一个id属性(当然,它应该在整个文档中是唯一的.)这可能会让SVG处理器感到困惑.

我的理论似乎通过改变克隆途中的ID来证实:

$('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);
});
Run Code Online (Sandbox Code Playgroud)

......似乎可以防止这个问题.(在这种情况下,即使克隆渐变的ID已更改,克隆仍会获得渐变,因为它通过其ID找到原始渐变.)

JSFiddle:http://jsfiddle.net/2K4xv/2/

我猜测你的情况下发生的事情是处理器正在拾取你创建的第二个渐变滤镜元素,以便与第一个圆圈一起使用,然后当它被摧毁时丢失对它的引用你的empty(),因此留下你的圆圈,但没有渐变.究竟为什么这只是第二次发生的原因可能取决于SVG渲染器与HTML5文档交互的实现细节.

此前面的问题中有关于此问题的更多信息.


vio*_*313 1

@Matt Gibson 提出了一个 hack:鼓起新的 id,然后使用linearGradient引用原始linearGradient.

幸运的是,您确实需要这样做;)

标签的部分优势svg在于它们是自己的疯狂小容器。这样你就可以从 uri 外部引用东西。

&因此,如果您从事克隆业务,那么您可以抽象出模板模型并无限地重复使用它,而不用担心 ids:

$(document).ready(function(){
  $('input[value="copy"]').click(function () {
      $("#copydiv").append($(":first", "#orgdiv").clone());
  });

  $('input[value="clear"]').click(function () {
      $("#copydiv").empty();
  });
});
Run Code Online (Sandbox Code Playgroud)
<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>
Run Code Online (Sandbox Code Playgroud)

这也是你的 jsfiddle 的一个分支