6

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();
});

jsFiddle here

笔记:

  • 使用 jQuery 或 Javascript 进行克隆会导致相同的错误。
4

3 回答 3

7

我有一种预感,这可能是因为您正在克隆线性渐变,它具有一个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);
});

...这似乎可以防止问题。(在这种情况下,即使克隆渐变的 ID 发生了变化,克隆仍然会获得渐变,因为它通过 ID 找到原始渐变。)

JSFiddle在这里:http: //jsfiddle.net/2K4xv/2/

我猜在您的情况下“幕后”发生的事情是处理器正在拾取您为第一个圆使用而创建的第二个渐变过滤器元素,然后在它被破坏时失去对它的引用你的empty(),因此给你留下了圆圈但没有渐变。究竟为什么这只会发生第二次,这可能取决于 SVG 渲染器与 HTML5 文档交互的实现细节。

在这个较早的问题中有更多关于这个问题的信息。

于 2013-10-29T13:16:53.563 回答
2

克隆它后,您将拥有两个 id 为“r”的元素,一个在原始元素中,一个在克隆元素中。所有 id 必须是唯一的,因此文档不再有效。

于 2013-10-29T13:16:08.857 回答
1

@Matt Gibson 提出了一个技巧:鼓起新的 id,然后复制带有linearGradient引用原始linearGradient.

令人高兴的是,您是否需要这样做;)

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

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

$(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>

这也是你的 jsfiddle 的一个分支

于 2015-02-26T02:41:48.313 回答