88

I have a Javascript function that is passed a string. The string that it is passed is an entire webpage, including the header. I need the Javascript to replace the entire current page, head and all with the new content.

Consider the following HTML file:

<html>
  <head>
    <script language="Javascript">
      <!--
      var newContent='<html><head><script language="Javascript">function Hi() {alert("Goodbye World");}</script></head><body onload="Hi();">New Content</body></html>';
      function ReplaceContent(NC) {
        document.body.innerHTML=NC;
      }
      function Hi() {
        alert("Hello World");
        ReplaceContent(newContent);
      }
      -->
    </script>
  </head>
  <body onload="Hi();">
    Original Content
  </body>
</html>

In this case, the passed string is:

<html><head><script language="Javascript">function Hi() {alert("Goodbye World");}</script></head><body onload="Hi();">New Content</body></html>

But of course, since the "ReplaceContent" function is only replacing the body, but not the header, I never get the "Goodbye World" alert.

Ignoring "why I would want to do this", How can I dynamically replace the entire page, including the header, and javascript functions?

Please remember the "source" html ('newContent' above) exists only as a string, it does not exist on a server anywhere, so I cannot just redirect to it.

What changes I make to "ReplaceContent" above to cause the "Goodbye World" alert to appear once the content is replaced? Please keep in mind I cannot know in advance the value of the newContent variable!!

E_net4
  • 27,810
  • 13
  • 101
  • 139
Joshua
  • 6,643
  • 15
  • 55
  • 76

6 Answers6

82

Use document.write.

<html>
  <head>
    <script language="Javascript">
      <!--
      var newContent='<html><head><script language="Javascript">function Hi() {alert("Goodbye World");}</script></head><body onload="Hi();">New Content</body></html>';
      function ReplaceContent(NC) {
        document.open();
        document.write(NC);
        document.close();
      }
      function Hi() {
        ReplaceContent(newContent);
      }
      -->
    </script>
  </head>
  <body>
    Original Content
    <a href="javascript:Hi()">Replace</a>
  </body>
</html>
Macbric
  • 472
  • 4
  • 10
Dark Falcon
  • 43,592
  • 5
  • 83
  • 98
  • Although this is working for the provided example, if I try it on a real live page, like a facebook page, for example, it doesn't work. The code will work in an iframe, but when I try to "run" the same code by using document.write, I don't get the same result. What else could be missing? – Joshua Nov 27 '10 at 19:03
  • When do you attempt to execute it? Another thing you might try would be a document.open, as recommended in one of the other answers. – Dark Falcon Nov 27 '10 at 21:56
  • Does the script have to be in the head in this case? – GiantCowFilms Dec 29 '14 at 17:20
  • If you have javascript running on the ondocumentready event in the resulting html, it will not execute in IE11/Edge – jnoreiga Aug 22 '18 at 16:41
  • I tried using this method, but it writes the imported js variables again, therefore you get an error for declaring the same variables. Used document.querySelector('html').innerHTML instead – Roy Levy Apr 05 '20 at 09:11
16

Script

javascript:document.open('text/html');document.write('<!DOCTYPE HTML><html><head><meta http-equiv="Content-Type" content="text/html; charset=utf-8"><title>HAI</title></head><body><h1>OMG HAI2U!!!1</h1></body></html>');document.close();

DOM snapshot of the resulting page

<html><head><meta http-equiv="Content-Type" content="text/html; charset=utf-8"><title>HAI</title></head><body><h1>OMG HAI2U!!!1</h1></body></html>
Free Consulting
  • 4,300
  • 1
  • 29
  • 50
7

document.getElementsByTagName("html")[0].innerHTML Contains both head and body tags. I Usually avoid document.open\write\close

YoniXw
  • 425
  • 5
  • 12
5
$("html").html('your page html here');
Robin Maben
  • 22,194
  • 16
  • 64
  • 99
  • Robin, thanks for your answer.This changes the html content of the same page. Is it possible to change the content of another page with this content. Eg; From index.html I want to change index1.html content. Just like $("index1.html").html('your page html here'); – Nijil Nair Nov 05 '13 at 06:04
  • 1
    @NijilNair: I don't understand what you mean by another page. Do you mean you have several `iframe`s embedded in one page? – Robin Maben Nov 05 '13 at 06:33
0

Very late answer, but I had the same problem and solved it differently.

The various approaches overwriting the current page have some drawbacks:

  • they're all blocking - in case of large content, the page appears stuck for a moment
  • since it's replacing the entire page, you cannot do anything on the page in the meantime (like showing a spinner)
  • the approach tends to either use deprecated/unrecommended apis (such as document.write) or requires excessive coding (splitting the html, possibly recreating script tags etc)

In the end, I went with a simple iframe that covers the entire viewport and then used the srcdoc property to fill in the page. While the page is loading, I was able to show a spinner as well.

Here's an example:

<iframe id="the-iframe" frameborder="0"></iframe>
<div id="the-loader">loading...</div>
#the-iframe {
    position: fixed;
    top: 0;
    left: 0;
    right: 0;
    bottom: 0;
    width: 100%;
    height: 100%;
}
#the-loader {
    position: fixed;
    top: 0;
    left: 0;
    right: 0;
    bottom: 0;
    background: #FFFFFFDD;
}
const iframe = document.getElementById('the-iframe');
const loader = document.getElementById('the-loader');

iframe.onload = function () {
    iframe.style.display = 'block'; // <- Do this if you want to hide the iframe
                                    // by default while loading (but also add
                                    // `display: none` in its initial css).
    loader.style.display = 'none';
};
iframe.srcdoc = '<!DOCTYPE html><html>.............';
Christian
  • 27,509
  • 17
  • 111
  • 155
-5

var script = document.createElement('script');
script.src = 'http://code.jquery.com/jquery-1.7.2.min.js';
script.type = 'text/javascript';
document.getElementsByTagName('head')[0].appendChild(script);