Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Snap.svg can't find dynamically (and successfully) appended SVG element with jQuery

Snap.svg doesn't work in this case :

$('body').append($('<svg>').attr('id', 'test')) ;
console.log($('#test').length) ; // 1

var svg = Snap('#test') ;
svg.circle(100, 100, 50) ;
// Uncaught TypeError: Object [object Object] has no method 'circle'

... but works when the element is already in the HTML :

<body>
    <svg id="test"></svg>
</body>

The SVG element is successfully in the HTML but can't be found with Snap.svg. Am I doing it wrong with the first example or is it a bug ?

like image 519
Tot Avatar asked Nov 18 '13 10:11

Tot


1 Answers

It looks like you found a workaround, but I thought you, or anyone reading this question, might want an explanation.

To create SVG elements, you have to use document.createElementNS() because svg elements are part of different namespace than html elements. For example:

var elementHTML = document.createElement("svg"); //does not work
var elementSVG = document.createElementNS("http://www.w3.org/2000/svg", "svg"); //works!

and internally, jquery uses document.createElement() when you give it just a tag name. Once you have the element, you can wrap it as a jquery object, and use it as normal.

$(elementSVG).attr("width", 100); //etc.

Using $("<svg data-blah='asdf'>") or similar works because anything beyond a simple tag is put into an element via .innerHTML and then extracted out. By doing it this way, the same engine is used as if it were in the page's HTML markup. And the HTML5 spec now has special cases for what to do when encountering a <svg> element in the markup.

Some things to look out for when working with svg in jquery are:

  • attributes are not case sensitive, but some svg attributes are! For example, doing $element.attr("attributeName", "stroke") will not work.
  • .animate() has some problems, but you can use a custom step function to get around it.

More details about it here

like image 164
jcbelanger Avatar answered Nov 12 '22 01:11

jcbelanger