3

Working with IE 8, I am attempting to add two VML ovals (A,B) to my page, through javascript. Whichever oval is appended to the parent DIV is rendered, but I the second is not.

If I appendChild(A) then appendChild(B), Oval A is rendered, B is not. If I appendChild(B) then appendChild(A), Oval B is rendered, A is not.

document.namespaces.add("v","urn:schemas-microsoft-com:vml");

this.container = Document.getElementById(mydiv);

var grid2 = document.createElement("v:oval");
grid2.style.left=   "300px";
grid2.style.top=    "250px";
grid2.style.width=  "25pt";
grid2.style.height= "75pt";
grid2.style.position="absolute";
grid2.style.behavior="url(#default#VML)";
grid2.style.display="inline-block";
grid2.setAttribute("fillcolor","#FF0000");
grid2.setAttribute("id", "marker2");    

var grid = document.createElement("v:oval");
grid.style.left="100px";
grid.style.top="100px";
grid.style.width="94pt";
grid.style.height="164pt";
grid.style.position="absolute";
grid.style.behavior="url(#default#VML)";
grid.style.display="inline-block";
grid.setAttribute("fillcolor","#0000FF");
grid.setAttribute("id", "marker");

this.container.appendChild(grid2);
this.container.appendChild(grid);

Am I missing some trick to adding VML?

I have tried it in IE 9, with same results.

Due to corporate rules, only IE is supported within the company, and many users are still using IE8, so I cannot switch the HTML5 Canvas at this time.

Thanks for any suggestions

Scott S
  • 461
  • 7
  • 17
  • 1
    Why not use [Raphaël](http://raphaeljs.com/)? This has a *much* cleaner API; and will use VML for IE (And SVG for other browsers) so you'll have IE support. – vcsjones Dec 06 '11 at 18:40
  • What is the doctype of the HTML page, this makes an important difference rendering VML in IE? – Frodo Baggins Dec 06 '11 at 18:41
  • I have started looking at the Raphael library, it looks promising. As far as the DOCTYPE, I will verify what I have. David, and you are right, from my experience, IE is more sensitive to DOCTYPE then other browsers. Thanks for the quick suggestions. – Scott S Dec 08 '11 at 01:24

2 Answers2

3

I dealt with a similar problem, where the first VML object added to IE rendered properly, but subsequent ones were rendered too small to see.

This blog article was helpful in determining that IE doesn't support set/getAttribute for VML anymore:

http://louisremi.com/2009/03/30/changes-in-vml-for-ie8-or-what-feature-can-the-ie-dev-team-break-for-you-today/

It turns out not only do set/getAttribute not work, but even setting the attributes directly on the DOM element (e.g. grid2.style.left="300px") didn't work.

Ultimately, what seemed to work was generating all the markup for each element as a string, and injecting it into the DOM by setting it as another element's innerHTML.

var html2 = "<v:oval style=\"left: 300px; top: 250px; width: 25pt; height: 75pt; position: absolute; display: inline-block;\" fillcolor=\"#0000FF\" id=\"marker2\"></v:oval>";
var html = "<v:oval style=\"left: 300px; top: 400px; width: 94pt; height: 164pt; position: absolute; display: inline-block;\" fillcolor=\"#0000FF\" id=\"marker\"></v:oval>";

someNode.innerHTML = html2;
someNode2.innerHTML = html;

I made a dummy node which I used to host the VML: set innerHTML, then move it to the desired parent, repeat.

Ugly, but it worked!

Matt
  • 31
  • 3
0

Use a documentFragment to add the second node:

document.namespaces.add("v","urn:schemas-microsoft-com:vml");

this.container = document.documentElement;
var frag = document.createDocumentFragment();

var grid2 = document.createElement("v:oval");
grid2.style.left=   "300px";
grid2.style.top=    "250px";
grid2.style.width=  "25pt";
grid2.style.height= "75pt";
grid2.style.position="absolute";
grid2.style.behavior="url(#default#VML)";
grid2.style.display="inline-block";
grid2.setAttribute("fillcolor","#FF0000");
grid2.setAttribute("id", "marker2");    

var grid = frag.appendChild(document.createElement("v:oval"));
grid.style.left="300px";
grid.style.top="400px";
grid.style.width="94pt";
grid.style.height="164pt";
grid.style.position="absolute";
grid.style.behavior="url(#default#VML)";
grid.style.display="inline-block";
grid.setAttribute("fillcolor","#0000FF");
grid.setAttribute("id", "marker");

this.container.appendChild(frag);
this.container.appendChild(grid2);
Paul Sweatte
  • 24,148
  • 7
  • 127
  • 265