最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - Is it possible to work with jquery and Svg directly (no plugins)? - Stack Overflow

programmeradmin1浏览0评论

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

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:

/* Creating the svg container using pure JS */
var container = document.getElementById("svg_space");
mySvg = document.createElementNS("", "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("", "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.

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?

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

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:

/* 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.

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?

Share Improve this question asked May 27, 2011 at 6:57 Jesufer VnJesufer Vn 13.8k6 gold badges21 silver badges28 bronze badges 4
  • 3 >I'm trying to work with Jquery and Svg together. But I don´t want to use any plugin. - could you please describe why? Existing plugins and libraries have good documentation, examples, structure... Take a look to keith-wood.name/svg.html for example. – silex Commented May 27, 2011 at 8:14
  • Are you aware that .attr() can take a JavaScript object with key-value pairs? E.g. you could just do $(mySvg).find("circle").attr({ cx: 160, cy: 70, r: 30, "class": "class1" }); – Domenic Commented May 27, 2011 at 8:30
  • It is not a cross-browser problem, because I test it in several browsers. – Jesufer Vn Commented May 27, 2011 at 19:43
  • possible duplicate of jquery's append not working with svg element? – givanse Commented Feb 22, 2014 at 20:53
Add a comment  | 

3 Answers 3

Reset to default 13

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 />").

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

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

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.

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

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

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

发布评论

评论列表(0)

  1. 暂无评论