0

I want to use separate javascript file to dynamically add a tag into a HTML file, but always get an error: Cannot read property 'appendChild' of undefined. Really confused. Can anyone help ? Thank you so much! Below is my code in a .js file:

var canvasGraphic = (function(){
    return {
        getCanvas:function(){
            var canvas = document.createElement("canvas");
            var body = document.getElementsByTagName("body")[0];
            body.appendChild(canvas);
            canvas.style.border = "black solid";
        }
    }
})();

canvasGraphic.getCanvas();
3
  • Can you try debugging by setting your browser debugger to pause on all exceptions? This snippet runs in a Stack Overflow snippet. Where are you putting your <script src="..."></script>? Before or after <body>? Commented Dec 14, 2016 at 19:41
  • Yeah, if I run this code in the same HTML file, after add a <script> tag, that's fine, but move to a .js file, it throws this error Commented Dec 14, 2016 at 19:46
  • 1
    Add the HTML file to your question. Commented Dec 14, 2016 at 19:50

4 Answers 4

2

The message you are getting means that document.getElementsByTagName("body")[0] has returned undefined. (That's why the error message says appendChild does not exist as a method of body.)

Is your code running before the document has loaded?

In that case, you might not be able to find the body element. If you can move your script element to the bottom of the body tag, do that instead (suggested here first by A.J.).

<body>
    <main>All your content, tags, whatever...</main>
    <script src="your-code.js"></script>
</body>

Otherwise, you might need to attach an event handler to the DOMContentLoaded event.

Also, note that document.body will get the body tag of a document.

document.addEventListener('DOMContentLoaded', function() {
  var canvasGraphic = (function() {
    return {
      getCanvas: function() {
        var canvas = document.createElement("canvas");
        document.body.appendChild(canvas);
        canvas.style.border = "black solid";
        return canvas;
      }
    }
  })();

  canvasGraphic.getCanvas();
})

An aside: you probably wanted to return canvas from your getCanvas function

Sign up to request clarification or add additional context in comments.

Comments

1

Where does this code exist in the lifecycle of the page? Are you certain that the document has loaded and is ready before getCanvas() is called?

Let's use this example index.html document. It will display your error:

<html>
<head>
<script type="text/javascript">
var canvasGraphic = (function(){
    return {
        getCanvas:function(){
            var canvas = document.createElement("canvas");
            var body = document.getElementsByTagName("body")[0];
            body.appendChild(canvas);
            canvas.style.border = "black solid";
        }
    }
})();

canvasGraphic.getCanvas();
</script>
</head>
<body>
</body>
<html>

However if we put the call to getCanvas() inside another function and call that function onload of the body, the error disappears:

<html>
<head>
<script type="text/javascript">
var canvasGraphic = (function(){
    return {
        getCanvas:function(){
            var canvas = document.createElement("canvas");
            var body = document.getElementsByTagName("body")[0];
            body.appendChild(canvas);
            canvas.style.border = "black solid";
        }
    }
})();

function initialize() {
    canvasGraphic.getCanvas();
}
</script>
</head>
<body onload="initialize();">
</body>
<html>

There are many ways to get this accomplished, this one was easy. The key is to be sure that your documents DOM has finished loading before calling your function.

HTH!

Comments

1

There seems to be nothing wrong with your code. Just load your script file at the end of the body tag, or execute the code after the DOM's readyState is ready.

var canvasGraphic = (function() {
  return {
    getCanvas: function() {
      var canvas = document.createElement("canvas");
      var body = document.getElementsByTagName("body")[0];
      body.appendChild(canvas);
      canvas.style.border = "black solid";
    }
  }
})();

canvasGraphic.getCanvas();

Comments

0

The code runs well on a JSfiddle: https://jsfiddle.net/vazu4wj5/

The only change I would suggest is to change body.appendChild(canvas); to document.body.appendChild(canvas);, it's just more specific.

Here's the final code:

var canvasGraphic = (function(){
    return {
        getCanvas:function(){
            var canvas = document.createElement("canvas");
            var body = document.getElementsByTagName("body")[0];
            document.body.appendChild(canvas);
            canvas.style.border = "black solid";
        }
    }
})();

canvasGraphic.getCanvas();

1 Comment

In that case, you don't really need var body = document.getElementsByTagName(... anymore.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.