0

I am using the following function to set up DOM elements using Javascript:

  createDomEl(type, parentEl, id) {
    let el = document.createElement(type);
    parentEl.appendChild(el);
    el.id = id;

    return el;
    }

It works just fine, unless I try to append a DOM element to document.body. I have tried passing in the body element several ways, including:

const body_el = document.body;

or

const body_el = document.getElementsByTagName('body')[0];

and

createDomEl('section', body_el, 'main-section');

But I get the TypeError: parentEl.appendChild is not a function.

EDIT: I've moved the script tag to be inside the body, like so:

<!DOCTYPE html>
<html>
<head>
 ...
</head>
<body>
 <script src="build/bundle.js"></script>
</body>
</html>

I can log the body element before calling this function, i.e.

console.log(body_el)

This logs:

<body>...</body>

I can also directly substitute document.body for parentEl in the function, and the function works. The issue seems to be passing it in.

The createDomEl function is in a class imported into a main class from which it is called as a method of an instance, like so:

import CreateDomEls from './helpers/createDomEls.js';

class Layout {
  constructor(config) {
    this.createDomEls = new CreateDomEls();
    this.createMainSection();
  }

  createMainSection() {
    const body_el = document.getElementsByTagName('body')[0];
    console.log(body_el);
    const mainSection = this.createDomEls.createDomEl(
      'section',
      body_el,
      'main-survival-game-station'
    );
  }
interwebjill
  • 720
  • 7
  • 27
  • Can you show where this script runs in your HTML? Is it in the ``? – CertainPerformance Apr 08 '19 at 01:00
  • Please post a [Minimal, Complete, and Verifiable example](https://stackoverflow.com/help/mcve) – Ele Apr 08 '19 at 01:00
  • 1
    ` – Phil Apr 08 '19 at 01:04
  • 1
    Works fine here https://jsfiddle.net/ev6o28fx/1 – charlietfl Apr 08 '19 at 01:05
  • 1
    The JSFiddle works because it already defines the body and script order for you. This is an HTML issue, not a JS issue. – Soviut Apr 08 '19 at 01:08
  • @Phil I am able to log the body element before calling the function. Also, if I substitute document.body for parentEl in parentEl.appendChild(el), the function executes. So I'm not sure this is matter of it not finding the body element. Could there be an error in passing the body element as an argument? – interwebjill Apr 08 '19 at 01:32

1 Answers1

0

Your script tag is outside (below) the closing </body> tag. The script tag must be inside the <body></body> or <head></head> block in order to be run. It will be ignored if it's at the document (<html></html>) level.

Move your <script> tag to the end of the body, that way you can guarantee the body has loaded by the time the script is executed.

<body>
  ...
  <script>
    // this will run once the body has loaded
  </script>
</body>

Additionally, you can leave the script in the head and listen for a document loaded event. These days you can usually rely on

window.onload = function() {
  // your code which manipulates the document here
  createDomEl('section', body_el, 'main-section')
}

Note that only the code that does the manipulation of the DOM needs to go inside the window.onload event handler. The functions themselves can live outside this handler.

Soviut
  • 79,529
  • 41
  • 166
  • 227