2

After fetching an SVG document using XHR I need to append a portion of it from the responseXML document into the current document. Using this code works on Safari/Chrome/FireFox, but does not work on IE9:

var xhr = new XMLHttpRequest;
xhr.open('get','stirling4.svg',true);
xhr.onreadystatechange = function(){
  if (xhr.readyState != 4) return;
  var g = xhr.responseXML.getElementsByTagName('g')[2];
  var p = document.getElementsByTagName('path')[0];
  p.parentNode.insertBefore(document.importNode(g,true),p);
};
xhr.send();

IE9 throws a script error when calling importNode:

SCRIPT16386: No such interface supported

I found a question where someone else reports a similar problem. You can see a live example of this problem on my website. (The SVG file itself displays a fractal, uses XHR to fetch another SVG file, uses one technique to manually import one of the nodes and then attempts to use importNode to import another node. One Chrome, Safari, or Firefox you see two grey diamonds imported into the document, while on IE9 only the first diamond works.)

How can I make importNode work with IE9?

Phrogz
  • 296,393
  • 112
  • 651
  • 745

1 Answers1

3

Here's a workaround solution that manually 'imports' the node by using a custom function to recursively clone all portions of it instead of using importNode. This code is used on my example page to import one of the two shapes.

var xhr = new XMLHttpRequest;
xhr.open('get','stirling4.svg',true);
xhr.onreadystatechange = function(){
  if (xhr.readyState != 4) return;
  var g = xhr.responseXML.getElementsByTagName('g')[2];
  var p = document.getElementsByTagName('path')[0];
  p.parentNode.insertBefore(cloneToDoc(g),p);
};
xhr.send();

function cloneToDoc(node,doc){
  if (!doc) doc=document;
  var clone = doc.createElementNS(node.namespaceURI,node.nodeName);
  for (var i=0,len=node.attributes.length;i<len;++i){
    var a = node.attributes[i];
    clone.setAttributeNS(a.namespaceURI,a.nodeName,a.nodeValue);
  }
  for (var i=0,len=node.childNodes.length;i<len;++i){
    var c = node.childNodes[i];
    clone.insertBefore(
      c.nodeType==1 ? cloneToDoc(c,doc) : doc.createTextNode(c.nodeValue),
      null
    );
  }
  return clone;
}
Phrogz
  • 296,393
  • 112
  • 651
  • 745
  • I'm happy to accept a better solution if someone can find a workaround that allows `importNode` to work correctly. – Phrogz May 23 '11 at 15:31