Problem in js, canvas is null


#1

Hi good day everybody I have this code(not in codecademy)
in HTML:

<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width">
    <title>test</title>
    <link href="style.css" rel="stylesheet" type="text/css" />
  </head>
  <body>
    <script src="script.js"></script>
    <canvas id="canvas"></canvas>
  </body>
</html>

In css(just in case but there isn’t a problem):

canvas {
	outline: 1px solid #000;
	width: 500px;
	height: 500px;
}

And actually here’s the problem(in JS[no libraries]):

var canvas = document.querySelector("#canvas")
var context = canvas.getContext('2d');

var xPos = 0;
var yPos = 0;
context.rect(xPos, yPos, 50, 50);
context.stroke();

function move(e) {

	alert(e.keyCode)

	if (e.keyCode == 39) {
		//right key
		xPos = xPos + 5;
	}
	else if (e.keyCode == 37) {
		//left key
		xPos = xPos - 5;
	}
	else if (e.keyCode == 38) {
		//up key
		yPos = yPos - 5;
	}
	else if (e.keyCode == 39) {
		//down key
		yPos = yPos + 5;
	}

	document.canvas.width = document.canvas.width;
	context.rect(xPos, yPos, 50, 50);
	context.stroke();
}

document.onkeydown = move;

It says:
TypeError: canvas is null
[unreachable link]
If there aren’t enough details just comment what you’ll need to know


#2

This happens because your script executes before the canvas is loaded, try it this way:

<body>
    <canvas id="canvas"></canvas>
    <script src="script.js"></script>
</body>

#3

Order is not a concern, here, since the script isn’t accessing anything until an event occurs. That can’t happen until the HTML is loaded.

However, the placement of a script element before a body child element suggests the script should go into the HEAD, and not be in the body. Given that this script has no runtime node dependencies it is fine to load it in the head.

Kick me in the foot! How did I not see that line? Belay all the above… There is a node dependency, #canvas. Shut the front door!

That does change the scenario and does require that we defer the script until the HTML is loaded so the nodes are in the DOM. The simplest way to defer is to load the script at the bottom of the body element.

  <script src=""></script>
</body>

#4

Thank you that worked.


#5

Thank you too for the answer.