7
var newDoc = document.implementation.createHTMLDocument('someTitle');
// swap newDoc with document

DOMImplementation.createHTMLDocument

  • Is it possible to swap the current document for a new document?
  • Is there any reasonable reason to do this?
Raynos
  • 166,823
  • 56
  • 351
  • 396
  • You probably can not. `window.document` itself is readonly and there are no methods on `window` to do change its linked `document`. I could not find any source to justify my assumption however. – copy Dec 31 '11 at 18:58
  • 1
    I thought the same but there might be something out there. I mean whats the point of creating a new document if you cant inject it into a window. Maybe you can inject it into a new window / iframe – Raynos Dec 31 '11 at 19:22
  • 1
    Yeah, you can inject it into an iframe, that's the [MDN's example](https://developer.mozilla.org/en/DOM/DOMImplementation.createHTMLDocument) for createHTMLDocument (__Update__: Not directly though. But you can play around with `importNode` and `replaceChild(importedDocumentElement, document.documentElement)`). It can also be used to parse HTML you get from a http request (and then have a DOM representation of that). – copy Dec 31 '11 at 19:42
  • @Raynos I spoke with you in the PHP chat room before. Hope you are doing good. Thanks for the advice before. You are a cool dude. – King Friday Jan 01 '12 at 00:23
  • 1
    @copy a document and a documentElement are radically different. (try `Document.prototype.isPrototypeOf(document.documentElement` which is false) – Raynos Jan 01 '12 at 10:43

3 Answers3

6

You cannot replace the current document object or any document object with the Document object created with createHTMLDocument method.

The createHTMLDocument was first introduced in one of the drafts of the DOM Level 2 Core, but was later removed from the final recommendation.

It was later added to the HTML5 spec as there was no programmatic way to create an HTML document.

Some of the use cases provided for programmatic creation of an HTML document were,

  • Create a non-rendered HTML document to upload via XMLHttpRequest (instead of sending an XML document).

  • Feature-test the HTML DOM in library code in a way that is guaranteed to avoid side effects on the displayed document.

  • Create an isolated non-rendered document from a rich text editing area, so client-side cleanup can be done before uploading without disturbing the live DOM that the user may still edit further.

  • Implement HTML5 parsing algorithm client-side in JavaScript for testing and comparison purposes, or for virtualization or object-capability-based security.

    An invisible iframe can be used for most of these purposes but that is more expensive in terms of resources. W3C mailing list

The conversation on W3C mailing lists that brought the method back into the spec, [Bug 7842] New: No programmatic way to make an HTML document - consider adding createHTMLDocument

Livingston Samuel
  • 2,422
  • 2
  • 20
  • 35
5

There is stuff in the document that is not really related to the DOM tree it contains, such as document.cookie, location and URL. It's much safer if we cannot replace global objects like window and document.

But what you are looking for can be effectively achieved by replacing the main document's documentElement with the other document's documentElement. It will have exactly the same effect that you are looking for.*

document.replaceChild(
    document.importNode(newdoc.documentElement, true),
    document.documentElement
);

As for reasons to do it, I have so far found one that cannot be achieved with an iframe.

* Note that if the doctypes are different, you'd have to replace the main document's doctype node with the other document's doctype node separately.

Community
  • 1
  • 1
Esailija
  • 138,174
  • 23
  • 272
  • 326
2

If you serialize the document to HTML you can replace the document of the current page with document.open,document.write and document.close.

In fact you can even change Quirks mode to standard mode by adding a <!doctype html>.

For example: http://jsbin.com/anusul/2

<html>    
    <script>
        alert('now in compatMode '+document.compatMode);
        if (document.compatMode==='BackCompat') {
            setTimeout(function() {
        var markup= '<!DOCTYPE html>New Page';
                document.open();
                document.write(markup);
                document.close();
            }, 0);
        }
    </script>
</html>​​​​​​

I wouldn't advise using it such trickery without a special case scenario, but it does work.

source: Javascript switch from quirksmode to standard + Need help with: jquery prepend doctype to html

Community
  • 1
  • 1
Lime
  • 13,400
  • 11
  • 56
  • 88
  • That's not very interesting, because you have to use a HTML string. I was more interested in using a Document element – Raynos Feb 22 '12 at 02:47
  • 2
    When referring to the original question, It certainly does allow you to replace a document. Its understandable if that wasn't what you were looking for within the context of `DOMImplementation.createHTMLDocument` statement – Lime Feb 22 '12 at 04:32