开发者问题收集

HTML5 Canvas 绘图 GetContext(“2d”) - Null 不是对象 (variable.getContext)

2015-08-11
7068

尝试按照 Youtube 上的教程创建 HTML5 Canvas 时钟时。我按照说明操作,但在整个演示过程中,我无法在自己的浏览器(Safari 8.0.7 和 FireFox 39.0.3)上查看时钟,它显示空白屏幕 - 好像那里没有代码。在 Safari 中的开发人员菜单(检查元素)中查看后,我被告知 JavaScript 代码中存在此错误消息:


TypeError:null 不是对象(评估“myVariable.getContext”)


看到此消息后,我决定放置消息框“断点”以发现代码停止执行的位置。我使用该方法了解到它确实与 getContext("2d") 方法有关。

我想借此机会与您分享我的代码。请注意,有一个循环可以每 40 毫秒刷新一次此时钟,以便从秒时钟获得平滑的运动。

这是我的代码:

window.alert("1");
/*Status -- Worked*/
var c = document.getElementById("canvas");
window.alert("2");
/*Status -- Worked*/
var ctx = c.getContext("2d");
window.alert("3");
/*Status -- Failed to show in Safari*/

ctx.strokeStyle = "28d1fa";
ctx.lineWidth = 17;
ctx.shadowBlur = 15;
ctx.shadowColor = "28d1fa";

function degToRad(degree) {
  "use strict";
  var factor = Math.PI / 180;
  return degree * factor;
}

function renderTime() {
  //Variables
  "use strict";
  var now = new Date();
  var today = now.toDateString();
  var time = now.toLocaleTimeString();
  var hours = now.getHours();
  var minutes = now.getMinutes();
  var seconds = now.getSeconds();
  var milliseconds = now.getMilliseconds();
  var newSeconds = seconds * (milliseconds / 1000);

  //Background
  gradient = ctx.createRadialGradient(250, 250, 5, 250, 250, 300);
  gradient.addColorStop(0, "09303a");
  gradient.addColorStop(1, "black");
  ctx.fillStyle = gradient;
  ctx.fillStyle = "333333";
  ctx.fillRect(0, 0, 500, 500);

  //Hours
  ctx.beginPath();
  ctx.arc(250, 250, 200, degToRad(270), degToRad((hours * 15) - 90));
  ctx.stroke();

  //Minutes
  ctx.beginPath();
  ctx.arc(250, 250, 170, degToRad(270), degToRad((minutes * 6) - 90));
  ctx.stroke();

  //Seconds
  ctx.beginPath();
  ctx.arc(250, 250, 140, degToRad(270), degToRad((newSeconds * 6) - 90));
  ctx.stroke();

  //Date
  ctx.font = "25px Arial bold";
  ctx.fillStyle = "28d1fa";
  ctx.fillText(today, 175, 250);

  //Time
  ctx.font = "15px Arial";
  ctx.fillStyle = "28d1fa";
  ctx.fillText(time, 175, 280);


}

setInterval(renderTime, 40);
<!DOCTYPE html>
<html>

<head>
  <meta charset="utf-8">
  <title>Project</title>
</head>

<body>
  <script type="text/javascript" src="script/script.js"></script>
  <canvas id="canvas" width="500" height="500"></canvas>
</body>
</body>

</html>

在您方便的时候,您能帮助我解决这个问题吗?

我将不胜感激。

感谢您的时间。

真诚的,

Coder 206

3个回答

问题在于您在画布加载之前就加载了 JavaScript,因为 <script> 标记位于页面的较高位置。

在画布之后加载 JavaScript,并且 document.getElementById("canvas"); 将不会为 null ,因为画布已经加载到页面上了。

<body>
  <canvas id="canvas" width="500" height="500"></canvas>
  <script type="text/javascript" src="script/script.js"></script>
</body>
Robin James Kerrison
2015-08-11

您应该等待页面加载完毕后再尝试执行 javascript。

因此请将您的 javascript 代码包装在里面:

window.onload=function(){

    ... your code ...

}
markE
2015-08-11

感谢 Robin James Kerrison 和 markE。

致:Robin James Kerrison

非常感谢您的澄清!这对我以后有帮助!

致:markE

感谢您的帮助,这是我出错时的备份 ;)

致:所有人

感谢上述伟大的 Stack Overflow 用户,这是我正常运行的代码。

var c = document.getElementById("canvas");
var ctx = c.getContext("2d");

ctx.strokeStyle = "28d1fa";
ctx.lineWidth = 17;
ctx.shadowBlur = 15;
ctx.shadowColor = "28d1fa";

function degToRad(degree) {
  var factor = Math.PI / 180;
  return degree * factor;
}

function renderTime() {
  //Variables
  var now = new Date();
  var today = now.toDateString();
  var time = now.toLocaleTimeString();
  var hours = now.getHours();
  var minutes = now.getMinutes();
  var seconds = now.getSeconds();
  var milliseconds = now.getMilliseconds();
  var newSeconds = seconds + (milliseconds / 1000);

  //Background
  var gradient = ctx.createRadialGradient(250, 250, 5, 250, 250, 300);
      gradient.addColorStop(0, "09303a");
      gradient.addColorStop(1, "black");
  ctx.fillStyle = gradient;
  ctx.fillStyle = "333333";
  ctx.fillRect(0, 0, 500, 500);

  //Hours
  ctx.beginPath();
  ctx.arc(250, 250, 200, degToRad(270), degToRad((hours * 15) - 90));
  ctx.stroke();

  //Minutes
  ctx.beginPath();
  ctx.arc(250, 250, 170, degToRad(270), degToRad((minutes * 6) - 90));
  ctx.stroke();

  //Seconds
  ctx.beginPath();
  ctx.arc(250, 250, 140, degToRad(270), degToRad((newSeconds * 6) - 90));
  ctx.stroke();

  //Date
  ctx.font = "25px Arial bold";
  ctx.fillStyle = "28d1fa";
  ctx.fillText(today, 175, 250);

  //Time
  ctx.font = "15px Arial";
  ctx.fillStyle = "28d1fa";
  ctx.fillText(time, 175, 280);


}

setInterval(renderTime, 40);
<!DOCTYPE html>
<html>
    <head>
        <meta charset="utf-8">
        <title>Project</title>
        <link rel=""
    </head>
    <body>
        <canvas id="canvas" width="500" height="500"></canvas>
        <script src="script/script.js"></script>
    </body>
</body>
</html>
Coder206
2015-08-11