【问题标题】:SVG turns black when clonedSVG在克隆时变黑
【发布时间】:2013-11-08 15:33:59
【问题描述】:

当我发现一个奇怪的行为时,我正在使用 jQuery 的 clone() 函数。

此代码重现了该问题。第一个 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 进行克隆会导致相同的错误。

【问题讨论】:

    标签: javascript jquery html svg clone


    【解决方案1】:

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

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

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

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

    this earlier question 中有关于此问题的更多信息。

    【讨论】:

    【解决方案2】:

    一旦你克隆了它,你就会有两个 id 为“r”的元素,一个在原始元素中,一个在克隆元素中。所有 id 必须是唯一的,因此文档不再有效。

    【讨论】:

    • 谢谢!!我遇到的问题与原始问题基本相同。我有两个使用相同渐变的 div。我显示/隐藏它们,而另一个总是可见的。在隐藏/显示第二次潜水几次后,渐变在始终可见的 div 上变为黑色。我显示第二个 div,一切都很好。我隐藏它,第一个 div 上的渐变变黑。现在我根据传入构造函数的字符串向渐变的 id 添加额外的文本。现在渐变保持不变!非常感谢比尔
    【解决方案3】:

    @Matt Gibson 提出了一个 hack:鼓起新的 id,然后使用重复的 html 和引用原始 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>

    还有here's a fork of your jsfiddle

    【讨论】:

      猜你喜欢
      • 2017-01-28
      • 2013-10-03
      • 2018-06-23
      • 1970-01-01
      • 2020-04-26
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多