是否可以直接使用 jquery 和 Svg(无插件)?

Posted

技术标签:

【中文标题】是否可以直接使用 jquery 和 Svg(无插件)?【英文标题】:Is it possible to work with jquery and Svg directly (no plugins)? 【发布时间】:2011-09-03 04:19:49 【问题描述】:

我正在尝试将 Jquery 和 Svg 一起使用。但我不想使用任何插件。

我现在处理的问题是,当我尝试使用传统的附加模式将子项添加到 svg 文档时,对象没有呈现。让我们看看我试图做什么:

/* Creating the svg container using pure JS */
var container = document.getElementById("svg_space");
mySvg = document.createElementNS("http://www.w3.org/2000/svg", "svg");
mySvg.setAttribute("version", "1.2");
mySvg.setAttribute("baseProfile", "tiny");
container.appendChild(mySvg);

/* Adding a child and setting attributes to the SVG container using pure JS */
Circle = document.createElementNS("http://www.w3.org/2000/svg", "circle");
Circle.setAttribute("cx", "60");
Circle.setAttribute("cy", "30");
Circle.setAttribute("r", "13");
Circle.setAttribute("class", "class1");
    mySvg.appendChild(Circle); /* After this, the circle is rendered */

/* Then, I tried to use jQuery to perform the same action... */
$(mySvg).append("<circle />");
$(mySvg).find("circle").attr("cx","160");
$(mySvg).find("circle").attr("cy","70");
$(mySvg).find("circle").attr("r","30");
$(mySvg).find("circle").attr("class","class1" );

...但是在这个动作之后,圆圈没有渲染。我在 Developers Tool Inspector 中检查了至少该圆圈是否真的附加到了 DOM 树中,我发现这两个元素都存在,并且之前设置了正确的属性,但是使用 jQuery 创建的圆圈就好像它是一个 html 后代,而不是 svg 的后代。这意味着与 svg circle 元素相关的构造函数、原型和其他方法不是 this 'jquery' circle 的一部分,而是与纯 html 标记相关。

有没有办法使用 jquery 将 svg 元素创建为 svg 后代,还是使用纯 javascript 更好?

【问题讨论】:

>我正在尝试将 Jquery 和 Svg 一起使用。但我不想使用任何插件。 - 你能描述一下原因吗?现有的插件和库都有很好的文档、示例、结构......例如,看看keith-wood.name/svg.html。 你知道.attr() 可以接受一个带有键值对的JavaScript 对象吗?例如。你可以做$(mySvg).find("circle").attr( cx: 160, cy: 70, r: 30, "class": "class1" ); 不是跨浏览器的问题,因为我在几个浏览器中测试过。 jquery's append not working with svg element?的可能重复 【参考方案1】:

这适用于 Chrome 11。尚未在其他浏览器中尝试过。

$(mySvg).append("<svg><circle /></svg>");
$(mySvg).find("circle").unwrap();
$(mySvg).find("circle").attr("cx","160");
$(mySvg).find("circle").attr("cy","70");
$(mySvg).find("circle").attr("r","30");
$(mySvg).find("circle").attr("class","class1" );

据我了解,jQuery 通过将字符串传递给浏览器的原生 HTML 解析器来解析 html。 HTML 解析规则根据元素名称及其祖先元素为元素分配命名空间,因此要将 circle 元素放入 svg 命名空间,需要在 svg 元素内进行解析。

所以在这里,它被解析并附加到 &lt;svg&gt; 元素中,然后调用 unwrap 以删除创建的额外 svg 元素。这种 append-and-unwrap 模式有些丑陋,我希望有更好的 jQuery 知识的人可以找到更优雅的解决方案,但概念已经足够清晰了。

【讨论】:

【参考方案2】:

无法尝试,但我敢打赌这会奏效。而不是

$(mySvg).append("<circle />");

$(mySvg).append(document.createElementNS("http://www.w3.org/2000/svg", "circle"));

如果你打算不止一次这样做,也许

function svgEl(tagName) 
    return document.createElementNS("http://www.w3.org/2000/svg", tagName);


$(mySvg).append(svgEl("circle"));

这与通过$(document.createElement("div")) 而不是$("&lt;div /&gt;") 获得更好性能的旧技巧相同。

【讨论】:

我知道前提是“没有插件”,但是如果您进行大量 SVG(或其他 XML)处理,您可能会喜欢这个相当简单的插件:rfk.id.au/blog/entry/xmlns-selectors-jquery $(svgEl(tagname)) 允许您在追加之前调用attr 之类的方法【参考方案3】:

不要同时使用 jQuery 和 SVG。 jQuery 是为 DOM 操作而设计的,Raphael 是为 SVG 操作而设计的。

使用Raphael,这是一个为您制作 SVG 的 JavaScript 库。

你真的不应该以艰难的方式做每一件事,这只会导致问题。

【讨论】:

以上是关于是否可以直接使用 jquery 和 Svg(无插件)?的主要内容,如果未能解决你的问题,请参考以下文章

轻量级、易于使用的jQuery插件用于动画化SVG路径

如何使用 jQuery SVG 插件设置 SVG 矩形元素的背景图像?

5个超赞的画布Canvas,SVG和CSS3相关的jQuery插件

jQuery 单页无刷新插件

jQuery SVG - 悬停元素

是否可以直接在 Svelte 中渲染 SVG 元素?