views:

834

answers:

1

I need to insert an HTML string into the <head> tag of the current document DOM, one way is: you create a div element, fill its innerHTML, copy over item-by-item into your <head> element. But these methods do not work in IE/Opera for reasons given below, though in FF3 both the below methods work perfectly, and the browser processes the added STYLE/SCRIPT elements.

Is there any other way you can insert a string directly into <head> and have those items processed?


(Why they fail in IE/Opera)

Method 1 - Fails because innerHTML cannot parse/ignores META, STYLE, SCRIPT elements within the string

insertHtml = function(parentElem,htmlStr){

   var frag = document.createDocumentFragment();
   var temp = document.createElement('div');
   temp.innerHTML = htmlStr;

   // at this point, temp.childNodes.length=0

   while (temp.firstChild) {
       frag.appendChild(temp.firstChild);
   }
   // use native DOM methods to insert the fragment
   parentElem.insertBefore(frag, parentElem.childNodes[0]);
}


Method 2 - Fails because added STYLE/SCRIPT elements do not get processed by the browser

 document.getElementsByTagName("head")[0].innerHTML = htmlStr
 // although this populates the <head> tag successfully
+1  A: 

Here's a stupid hack that solves the problem. Prepend a non-empty string tag (node.nodeType === 3) to the htmlStr and everything will work:

var insertHtml = function(parentElem, htmlStr){

   var frag = document.createDocumentFragment();
   var temp = document.createElement('div');
   temp.innerHTML = "hack" + htmlStr;

   while (temp.firstChild) {
       if (temp.firstChild.nodeType === 1) {
            // add only element nodes
            frag.appendChild(temp.firstChild);
       } else {
            // remove the hack string
            temp.removeChild(temp.firstChild);
       }
   }

   parentElem.insertBefore(frag, parentElem.childNodes[0]);
}
Ionuț G. Stan
It works, but the added STYLE/SCRIPT elements still do not get processed by IE7 although Opera9 / FF3 / Safari4 works just fine.
Jenko
I tested in IE6 and it worked. I'll try when I get home with IE8 and IE8 in IE7 mode to see if I can workaround these too.
Ionuț G. Stan
I tested in the above settings and it seems to work. I don't have a pure IE7 installation to test on.
Ionuț G. Stan
Great then, because I've used code very similar to your own so hopefully it works in a production environment :)
Jenko