动态分组 SVG 元素

Posted

技术标签:

【中文标题】动态分组 SVG 元素【英文标题】:Grouping SVG elements dynamically 【发布时间】:2012-09-14 22:19:36 【问题描述】:

我正在尝试使用 javascript (jQuery) 将某些 svg 元素(如 recttext 等)动态包装到单个 g

这是 svg 最初的样子

<div id="container">
   <svg ...>
     <rect .../>
     <circle .../>
     <text ...>...</text>
   </svg>
</div>

我用来包装到 g 标记中的脚本(基于我收到的有用答案 @Inserting a (g) node in the middle of a tree (SVG) using jQuery)。

$("#container svg > *").wrapAll('<g id="parent" />');

转换后的svg 看起来像这样

<div id="container">
   <g id="parent">
     <svg ...>
       <rect .../>
       <circle .../>
       <text ...>...</text>
     </svg>
   </g>
</div>

但用户界面上什么也没有显示。甚至萤火虫也显示g 变灰(就像隐藏元素一样)。

调用$("#parent").show();sometime cases 中有效,但在not all 中有效

问题:

为什么动态创建的g默认隐藏? 为什么$("#parent").show() 工作不一致? 还有另一种(更好的)动态分组元素的方法吗? 我对 SVG 完全陌生,但对 jQuery 和 DOM 操作相对熟悉。我将 SVG 视为只是另一个标签的方式是错误的吗?

在 Firefox (15.0.1) 和 Chrome (21.0.1180.89) 上都试过,结果相同

【问题讨论】:

【参考方案1】:

我相信原因是因为 SVG 实际上与包含的 html 位于不同的命名空间内。当您将 HTML 片段传递给 JQuery(在您的情况下为 &lt;g id="parent" /&gt;)时,它是在 HTML 文档的命名空间中创建的,而不是在 SVG 中。

JQuery 并不真正适合创建和操作非 HTML 元素,尽管您可以通过使用原生 JavaScript + JQuery 的组合来实现中途旅行:

$("#btn").click(function() 
    var el = document.createElementNS('http://www.w3.org/2000/svg', 'g');
    var $el = $(el);
    $el.attr('id', 'parent');
    $("#container svg > *").wrapAll($el);
);

我以前使用 JQuery 成功地使用 Keith Wood's excellent JQuery plugin 操作 SVG 元素。你可能想看看那个。

This answer 更详细地讨论了 SVG 和 HTML 命名空间。

【讨论】:

谢谢,工作就像一个魅力 :) 关于命名空间的很好的解释,我试图避免 NS,我认为这是我的错误。我确实遇到了 svg 插件,但想避免它,因为这 1 行是我几乎需要做的唯一 svg,我想一次缩放一组 svg 元素,因此不得不将它们包裹在 @ 987654325@ 这就是我的全部用例。也感谢您的链接!

以上是关于动态分组 SVG 元素的主要内容,如果未能解决你的问题,请参考以下文章

使用 Javascript 动态添加时,SVG 元素无法正确缩放

在事件中动态更改 animateMotion SVG 元素的路径

动态 svg 图标?

使用动态 SVG 元素时 IE 11 “崩溃”

XML SVG:使矩形的坐标动态

当动态值匹配时,jQuery 按类对元素进行分组