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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/6148859/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-25 19:40:01  来源:igfitidea点击:

Is it possible to work with jquery and Svg directly (no plugins)?

javascriptjqueryhtmldomsvg

提问by Jesufer Vn

I'm trying to work with Jquery and Svg together. But I don′t want to use any plugin.

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

The problem I am dealing now is that when I try to work using the traditional append mode to add a child to the svg document, the object is not rendered. Let′s check out what I tried to do:

我现在正在处理的问题是,当我尝试使用传统的附加模式将子项添加到 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" );

...but after this action, the circle does not render. I check if at least the circle was really appended to the DOM tree in the Developers Tool Inspector, and I found out that both element exist, with the proper attributes previously set, but the circle created with jQuery was as if it were a html descendant, not as a svg descendant. This means that the constructors, prototypes and other methods related to a svg circle element was not part of the this 'jquery' circle, but instead the related to a pure html tag.

...但在此操作之后,圆圈不会呈现。我检查了至少圆是否真的附加到开发人员工具检查器中的 DOM 树,我发现这两个元素都存在,并且具有先前设置的正确属性,但是使用 jQuery 创建的圆就好像它是 html 后代一样,而不是作为 svg 的后代。这意味着与 svg circle 元素相关的构造函数、原型和其他方法不是这个 'jquery' 圆的一部分,而是与纯 html 标签相关。

Is there a way to create svg elements as svg descendants using jquery, or is better the use of pure javascript despite the loss of productivity?

有没有办法使用 jquery 将 svg 元素创建为 svg 后代,或者尽管生产力下降,但使用纯 javascript 更好?

采纳答案by Domenic

Haven't been able to try, but I bet this would work. Instead of

还没有尝试过,但我敢打赌这会奏效。代替

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

Do

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

If you plan on doing this more than once, maybe

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

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

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

This is the same as the old trick of getting better performance via $(document.createElement("div"))instead of $("<div />").

这与通过$(document.createElement("div"))而不是获得更好性能的老技巧相同$("<div />")

回答by Alohci

This works in Chrome 11. Haven't tried in other browsers.

这适用于 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" );

As I understand it, jQuery parses html by passing the string to the browser's native HTML parser. The HTML parsing rules assign a namespace to the element based on its name and its ancestor elements, so to get the circle element into the svg namespace it needs to be parsed inside an svg element.

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

So here, it is parsed and appended inside the <svg>element and then unwrap is called to remove the extra svg element created. This append-and-unwrap pattern is somewhat ugly, and I expect that someone with better jQuery knowledge can find a more elegant solution, but the concept is clear enough.

所以在这里,它被解析并附加到<svg>元素内,然后调用 unwrap 以删除创建的额外 svg 元素。这种追加和解包模式有点难看,我希望有更好的 jQuery 知识的人可以找到更优雅的解决方案,但概念已经足够清楚了。

回答by Raynos

Don't use jQuery and SVG together. jQuery was designed for DOM manipulation, Raphael is designed for SVG manipulation.

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

Use Raphaelwhich is a JavaScript library which does SVG for you.

使用Raphael,它是一个 JavaScript 库,可为您执行 SVG。

You really shouldn't do everything the hard way, it's just going to cause problems.

你真的不应该以艰难的方式做每件事,它只会引起问题。