1

I have a script tag in the head html tag. The script should add an event listener when the rest of the index.html file has loaded. Therefore, nothing should run prior to that happening. It is almost the same as adding the script tag at the end of the body except for the browser reading the javascript and causing a little bit of render-blocking.

index.html

<html>
    <head>
        //meta stuff
        <script src="https://unpkg.com/babel-standalone@6/babel.min.js"></script>
        <script src="https://unpkg.com/react@15/dist/react.js"></script>
        <script src="https://unpkg.com/react-dom@15/dist/react-dom.js"></script>
        <script type="text/javascript" src="./code/webapp.js"></script>
    </head>
    <body>
        <noscript>Javascript is not enabled!</noscript>
        <div id="root"></div>
    </body>
</html>

Here is the console error message I get from React:

Uncaught Error: _registerComponent(...): Target container is not a DOM element.
    at invariant (react-dom.js:18118)
    at Object._renderNewRootComponent (react-dom.js:9978)
    at Object._renderSubtreeIntoContainer (react-dom.js:10069)
    at Object.render (react-dom.js:10090)
    at App (webapp.js:formatted:28)

The weird part is that the function App() get fired during a window.onload or window.addEventListener('load'). I used this before on my personal website but I had a defer and async on the script tag so maybe that is why it always fired correctly.

webapp.js

...
function App() {
    console.log('App loading...');
    const reactroot = document.getElementById('root');
    var app = React.createElement(WebApp, null);
    ReactDOM.render( app, reactroot);
}
window.onload = App;

In case anyone suggest using document.ready(), I am trying to not rely on jQuery. I want to also use this for a production website, not just my personal portfolio. So I can't rely on adding defer/async to the script tag.

Related topics:

Cit5
  • 400
  • 5
  • 19

1 Answers1

1

You should use DomContentLoaded event instead of onload callback

document.addEventListener("DOMContentLoaded", function(event) {
    console.log("DOM fully loaded and parsed");
});

Check this question for more information about onload vs DomContentLoaded event

Caligone
  • 180
  • 6
  • same error and that actually fires before window load event. for the record, I don't mind moving my script tag either. I just don't understand why these event listeners aren't working the way I'm assuming they should. – Cit5 Sep 10 '17 at 16:26
  • Have you a html element (probably a div) with the id "root"? – Caligone Sep 10 '17 at 16:27
  • yeah I do. I'll add my index.html in the question. – Cit5 Sep 10 '17 at 16:31
  • imo, your issue seems to come from another direction. Maybe the top the webapp.js file? – Caligone Sep 10 '17 at 16:39
  • the only thing on the top of webapp.js is React classes and a const json object. Actually, maybe this is coming from left field but I have a service worker that caches files automatically. what if (this part sounds crazy), what if my app thinks window or the DOM is loaded from the cached file somehow. so that event has happened already but the new file hasn't loaded yet. The only issue though is that I am doing hard reloads. So this probably doesn't make sense. – Cit5 Sep 10 '17 at 16:41
  • I don't think jsfiddle would be as exact since in the html section, those script tags mean they are in the body I believe. But nonetheless, I still get the same error message. https://jsfiddle.net/citizencinco/svrnzgoo/3/#&togetherjs=x91Jld75jl – Cit5 Sep 10 '17 at 16:54
  • In your exemple, your variable reactroot is fill before the dom is loaded. You have to fill it inside your DomContentLoaded callback – Caligone Sep 10 '17 at 17:01