Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Removing an SVG element from the DOM using jQuery

I'm using jQuery to add an element to an embedded SVG like this:

 var rect = SVG('rect');
 $(rect).attr( { x: left,
                 y: top,
                 width: right - left,
                 height: bottom - top,
                 style: style } );
 $(parentElement).append(rect);

parentElement could be for example $('g:first', svgRoot), where svgRoot refers to the embedded SVG element.

function SVG(elementName) {
        return document.createElementNS('http://www.w3.org/2000/svg', elementName);
}

This works well, the new rectangle is shown in the browser and added to the DOM:

screenshot

However, removing this rectangle fails. It is still shown in the browser and present in the DOM:

$(rect).remove();

I also tried

rect.parentNode.removeChild(rect);

which results in the error message "Uncaught TypeError: Cannot call method 'removeChild' of null".

Do you have any idea how I can fix that? Using jQuery SVG or another plugin/framework is not possible in my project.

like image 794
sbaltes Avatar asked Feb 06 '13 17:02

sbaltes


2 Answers

I ended up solving this problem using groups.

I ended up with this code :

var group = getGroupByName(name);
group.parentNode.removeChild(group);

...

function getGroupByName(name) {
    var container = document.getElementById("container");
    var groups = container.getElementsByTagName("g");
    for(var i=0; i<groups.length; i++) {
        if(groups[i].getAttributeNS(null, "name") === name) {
            return groups[i];
        }
    }
    return null;
}

Where container is my main SVG element.

This is tried and true. Works properly.

EDIT

As pointed out in the comments. You can find this fiddle that works. Similar to your example. It creates 4 rectangles and removes the 2 first ones.

If you want to remove the first element you have to specify this :

$("rect").first().remove();

Or if you want to do something with ALL of your rectangles you could approach this with something of the sort :

$("rect").each(function() {
     ... //could remove them here
}

Edit 2

According to last comment, as long as you have the reference to the object, you can use it's variable to remove it.

This updated fiddle will show you that using lastRect you can remove this last rectangle that was added.

like image 61
blo0p3r Avatar answered Oct 15 '22 03:10

blo0p3r


I found that doing a .find("*") helped a lot, I'm guessing it flattens the DOM out and thus ignores any nesting complexities that jQuery can't handle (perhaps... this is my theory at least).

So for example this removes anything other than rect, g, svg elements.

$("svg").find("*").not("rect, g").remove();

A jSFiddle showing find() and removing svg elements

like image 27
Alex KeySmith Avatar answered Oct 15 '22 02:10

Alex KeySmith