3

I need to write an html string to an element and then read the resulting outer html from that element. I need this to work in IE10, latest FF, Chrome, Safari, Android, iOS Safari but not in any older browsers. In all non-ie browsers the following simple approach works:

var html = WIUI.createElement('html');
html.innerHTML =  htmlString;
console.log(html.outerHTML);

However in IE10 the above approach fails in one unacceptable way. Somehow the html element has a body tag matching that of the parent document, (NOT of the html string I give it!!! I assume this is a crazy bug in the browser itself). You can see this bug in action here: https://mod.it/iuu_1DcT, if you view that application in a browser besides IE10 the output body onload function will match the input body onload function. In IE10 it will set the output onload function to foo() no matter what the input is because foo is the onload function of the parent.

An alternative approach that does work in IE10 (and all modern browsers) is to create and iframe like so:

var iframe = document.createElement('iframe');
document.body.appendChild(iframe);
var doc = iframe.contentWindow.document;
doc.open();
doc.write(htmlString);
doc.close();
console.log(doc.documentElement.outerHTML);

However this has the unfortunate side effect that writing to the iframe actually causes the html to be executed which I do not want.

From my research something like so SHOULD work (and does in browsers that aren't IE)

var doc = document.implementation.createHTMLDocument('temp');
doc.open();
doc.write(htmlString);
doc.close();
console.log(doc.documentElement.outerHTML);

However in IE10 the doc.open line gives an "unspecified error". Can anyone give me any clue what is going on or why IE is so difficult to work with compared to other browsers for this type of task?

asutherland
  • 2,849
  • 4
  • 32
  • 50
  • Is there a reason you can't use jquery? Althought I've heard not all of jquery is working properly in IE 10 yet – Sam Shiles Feb 22 '13 at 13:53
  • I could use jquery, but its not obvious to me how to make it do exactly what I want. What exactly would the jquery code look like, I'm pretty inexperienced with it and the things I tried didn't work. – asutherland Feb 22 '13 at 14:10

2 Answers2

0

Try this mate:

<html>
  <head>
     <script src="http://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
  </head>
    <body>
    <textarea id="textArea" rows="4" cols="50">
       Empty area
    </textarea>
    <script type="text/javascript">
    jQuery.fn.outerHTML = function(s) {
    return s
        ? this.before(s).remove()
        : jQuery("<p>").append(this.eq(0).clone()).html();
    };

    function doSomething(text) {
       var $wrapper = $('#textArea');
       $wrapper.html('<html><head></head><body><div id="inner">' + text +'</div></body></html>');
       console.log($wrapper.outerHTML());
    }
    doSomething('test');
</script>
</body>
</html>

This will output: <textarea id="textArea" rows="4" cols="50">&lt;html&gt;&lt;head&gt;&lt;/head&gt;&lt;body&gt;&lt;div id="inner"&gt;test&lt;/div&gt;&lt;/body&gt;&lt;/html&gt;</textarea> to the console. I have NOT tested this in IE 10 as I don't have access to it. But it Should work.

Credit to Get selected element's outer HTML for the outerhtml implementation.

Edit:

Community
  • 1
  • 1
Sam Shiles
  • 10,529
  • 9
  • 60
  • 72
  • The problem is that the string I have is an entire html page (with an html tag, head tag, body tag, etc) so setting a div's html to that gives an error. – asutherland Feb 22 '13 at 16:05
  • So, you want to show the html of an entire page, as markup (html), not rendered out? I have update the example to do this. – Sam Shiles Feb 22 '13 at 18:41
  • will try this on IE10 in the morning, and mark as answer if it works thanks! – asutherland Feb 23 '13 at 04:56
  • this doesn't really do what I want in that it in no way parses or validates the html. I want the html actually parsed by the dom and then converted back to a string. This example doesn't care of the html is completely malformed. the reason is that (a) i need to do a bit of manipulation of the html and (b) that I need the form of the html standardized (ie putting with single quotes and lots of unneeded white space on the dom and then reading it off the dom converts it to ). – asutherland Feb 23 '13 at 13:05
0

You can work around this issue in IE10 simply by doing thing following:

var doc = document.implementation.createHTMLDocument('title');
html = doc.createElement('html');
html.innerHTML =  htmlString;
console.log(html.outerHTML);

For some reason creating a new document rather than using the existing one causes IE10 not to corrupt the body onload attribute.

asutherland
  • 2,849
  • 4
  • 32
  • 50