mustang2247 / svgweb

Automatically exported from code.google.com/p/svgweb
Other
0 stars 0 forks source link

appendChild on dynamically created svg root stops working after root is attached to document #423

Closed GoogleCodeExporter closed 8 years ago

GoogleCodeExporter commented 8 years ago
What steps will reproduce the problem?
1. Create an SVG root element: 
var svg = document.createElementNS(svgns, 'svg');
2. Create and append a circle, like
var circle = document.createElementNS(svgns, 'circle');
...
svg.appendChild(circle);
3. Add the svg root element to the document
svgweb.appendChild(svg, document.body);
4. Create and append a rect, like
var r= document.createElementNS(svgns, 'rect');
...
svg.appendChild(r);
5. Circle is shown but the rect is not.

What is the expected output? What do you see instead?
Expect both the circle and rect to show. Only the circle shows up.

What version of the product are you using? On what operating system,
browser, and version of Flash?
svgweb r1005
Microsoft Windows [Version 6.0.6002] (Vista 64bit Personal edition)
Internet Explorer Version 8.0.600.18828 (IE8 Quirks mode)
Adobe Flash Player version 9,0,124,0

Please provide any additional information below. Reduced test cases are
always appreciated!

Not sure if this is related to the known issue:
"DOM Mutation Events are not supported and will not fire for SVG nodes when
the Flash viewer is used (i.e. if you create an SVG circle and then attach
it to the document, a DOM Mutation event will not fire)." (from
http://codinginparadise.org/projects/svgweb/docs/UserManual.html#known_issues4
).

Basically I can create elements, append them to the root then append the
root to the document but any elements appended to the root after that don't
show up.

It's quite possible I'm doing something wrong here but if I use
document.body.appendChild(svg);
then the attached test case works with native rendering in Firefox.

Original issue reported on code.google.com by metaphorically@gmail.com on 22 Nov 2009 at 3:36

Attachments:

GoogleCodeExporter commented 8 years ago

Original comment by bradneub...@gmail.com on 11 Dec 2009 at 8:12

GoogleCodeExporter commented 8 years ago
Is there any workaround to add a new element to an SVG after the SVG has 
already 
been added to the document and displayed?  

Original comment by john.pit...@gmail.com on 20 Apr 2010 at 3:02

GoogleCodeExporter commented 8 years ago
The workaround is included below. Note that you need to attach a listener to 
the root
and "start over". This is due to the fact that the svg element and all children 
that
you add to the page with svg web is ultimately converted to a string and passed 
to a
flash control and a new set of javascript fake objects are created to provide 
access
to the flash innards. 

Therefore, you can't use any of your svg element references that were created 
prior
to the creation of the flash control. In fact, the root you add to the page is 
also
instantly invalidated. That 'real' root is actually never added to anything.

That is why I converted that line near the bottom to this.appendChild(r) 
instead of
svg.appendChild(r). In fact, the "this" variable in the load listener of the 
root is
the first valid reference you can use. 

This is all consistent with the current design of SVG Web right now. When you 
think
about it, it is hard to imagine how we can improve on this. For that reason, I
propose closing this issue.

      var svg = document.createElementNS(svgns, 'svg'); // don't need to pass in 'true'
      svg.setAttribute('width', '300');
      svg.setAttribute('height', '300');
      svg.setAttribute('viewBox', '0 0 320 200');

      var circle = document.createElementNS(svgns, 'circle');
      circle.setAttributeNS(null, "cx","150");
      circle.setAttribute("cy","150");
      circle.setAttribute("fill","red");
      circle.setAttribute("r","10");
      svg.appendChild(circle);

      svg.addEventListener('SVGLoad', function() {
        var r = document.createElementNS(svgns, 'rect');
        r.setAttributeNS(null, "rx","2");
        r.setAttribute("ry","2");
        r.setAttributeNS(null, "x","170");
        r.setAttribute("y","120");
        r.setAttribute("width","20");
        r.setAttribute("height","20");
        r.setAttribute("fill","green");
        this.appendChild(r);
      }, false);

      svgweb.appendChild(svg, document.body); // note that we call svgweb.appendChild

Original comment by grick23@gmail.com on 4 Jun 2010 at 4:47

GoogleCodeExporter commented 8 years ago
This is by design.

Original comment by grick23@gmail.com on 1 Jul 2010 at 4:52