1

I am trying to dynamically create an html document object in javascript and link it to a button on the page. However, when I run the below code I get the following error: "TypeError: The Document.body attribute must be an instance of HTMLElement." MDN Web APIs documentation states: "In an HTML document, the document.createElement() method creates the HTML element specified by tagName." Why then am I getting this error? How can I create an html document dynamically?

window.onload = function() {
    var new_document = new Document();
    var new_body = new_document.createElement("body");
    new_document.body = new_body;
}
soporific312
  • 167
  • 10
  • what do you want to do after creation? – zemil Jun 23 '19 at 16:47
  • Can you explain what you're actually trying to do? Replacing the body element makes very little sense when you have the ability to just clear the current document body and literally put _any content you want_ inside of it...? (with bonus points for remembering to use [history.pushState](https://developer.mozilla.org/en-US/docs/Web/API/History_API#Example_of_pushState()_method) so you're not a jerk to your users) – Mike 'Pomax' Kamermans Jun 24 '19 at 00:21
  • I was just exploring the Document constructor and functions and get caught up on errors I don't understand. No you would not really use this in practice but it bothered me that I didn't understand why I couldn't do it. – soporific312 Jul 10 '19 at 14:50

1 Answers1

3

This question has been answered. How to create Document objects with JavaScript

Check out MDN to learn how https://developer.mozilla.org/en-US/docs/Web/API/DOMImplementation/createHTMLDocument

The new Document() constructor is not used like this. You can find the reason you are getting this error if you use the console in your browser...


let doc = new Document();
doc.body;
// < null
doc.doctype;
// < null
// doc.doctype is a read only property also.
doc.__proto__;
// < Document {…}

// ‘document’ is the document the browser already created.

document.doctype;
// < “<!doctype html>“
document.__proto__;
//HTMLDocument {constructor: ƒ, Symbol(Symbol.toStringTag): "HTMLDocument"}

let body1 = doc.createElement('body');
let body = document.createElement('body');

body1.__proto__;
// Element {…}
body.__proto__;
// < HTMLBodyElement {…}

doc.body = body1;
// < Type Error: Not of type HTMLElement

// Now use the body element created by 'document'.

doc.body = body;
// Uncaught DOMException: Failed to set the 'body' property on 'Document': No document element exists.

// The body needs an document element to become a child node of.

let html = document.createElement('html');
doc.appendChild(html);
doc.body = body;
// No errors

doc.body;
// <body></body>


As we can see the new Document() constructor makes a completely blank Document with a prototype of Document. And when you create elements from it those elements have a prototype of Element.

The Document the browser created named document has a prototype of HTMLDocument and the elements it creates have a prototypes of HTMLElement. And this is what the setter of doc.body is looking for.

Nick Sugar
  • 379
  • 3
  • 5