Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/docker/10.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 变量在函数内部不起作用_Javascript - Fatal编程技术网

Javascript 变量在函数内部不起作用

Javascript 变量在函数内部不起作用,javascript,Javascript,为什么这不起作用 var canvas = document.getElementById('canvas'); var ctx = canvas.getContext('2d'); var img = new Image(); img.onload = function(){ ctx.drawImage(img,0,0); }; img.src = 'hero.png'; 但这是真的吗 var img = new Image(); img.onload = function(){

为什么这不起作用

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


var img = new Image();
img.onload = function(){
    ctx.drawImage(img,0,0);
};
img.src = 'hero.png';
但这是真的吗

var img = new Image();
img.onload = function(){
    var canvas = document.getElementById('canvas');
    var ctx = canvas.getContext('2d');
    ctx.drawImage(img,0,0);
};
img.src = 'hero.png';
如何使ctx变量成为全局变量,以便我可以在所有函数中使用?顺便说一句,在所有教程中,每个人都使用第一种方法


成功了

我怀疑原因在于时间:如果您的代码在
脚本
元素中,而您的
id为
“canvas”
的元素是在上面定义的,那么您的第一个代码块将不会在
文档中找到它。getElementById(“canvas”)
调用,因为它还不存在。通过等待图像加载,您可以稍后在图像存在时进行检查

如果我是正确的,解决方案是将
脚本
块移动到
正文
元素的末尾,就在关闭
标记之前(实际上是
画布
标记)

例如,代替:

<!-- ... -->
<script>
var canvas = document.getElementById('canvas');
var ctx = canvas.getContext('2d');


var img = new Image();
img.onload = function(){
    ctx.drawImage(img,0,0);
};
img.src = 'hero.png';
</script>
<!-- ... -->
<canvas id="canvas"></canvas>
<!-- ... -->
</body>

var canvas=document.getElementById('canvas');
var ctx=canvas.getContext('2d');
var img=新图像();
img.onload=函数(){
ctx.drawImage(img,0,0);
};
img.src='hero.png';
这样做:

<!-- ... -->
<canvas id="canvas"></canvas>
<!-- ... -->
<script>
var canvas = document.getElementById('canvas');
var ctx = canvas.getContext('2d');


var img = new Image();
img.onload = function(){
    ctx.drawImage(img,0,0);
};
img.src = 'hero.png';
</script>
</body>

var canvas=document.getElementById('canvas');
var ctx=canvas.getContext('2d');
var img=新图像();
img.onload=函数(){
ctx.drawImage(img,0,0);
};
img.src='hero.png';
无论如何,将脚本放在文件的底部是个好主意,更多信息:

我的最佳猜测是“线程”(或事件)

当您调用
getContext
时,它会初始化一个新的图形上下文,并希望在浏览器尝试重新绘制屏幕之前得到它的结果。通常情况下,只要第一个方法是同步运行的(换句话说,阻塞:它立即返回),它就不会有太大问题。但是,一旦浏览器需要异步执行某些操作,它就“厌倦了等待”您的上下文,并开始在不等待结果的情况下重新绘制屏幕,从而使您的上下文无效。然后,您需要初始化一个新的上下文,以便将内容绘制到画布上


这显然取决于浏览器的实现,我的猜测仅基于其他地方的图形环境(如CoreGraphics、OpenGL等)中发生的情况。图形运行在单个线程上,该线程不会简单地等待赶上其他线程。尽管Javascript抽象了很多内容,但在构建图形应用程序时需要记住这一点。

因为html尚未加载,而且“canvas”元素不存在

您可以尝试以下方法:

var canvas, ctx;
var img = new Image();
img.onload = function(){
    canvas = document.getElementById('canvas');
    ctx = canvas.getContext('2d');
    ctx.drawImage(img,0,0);
};
img.src = 'hero.png';

ctx是在你们的主函数中声明的吗?这是你们的全部代码吗?不,不是所有的代码ctx都是在文件的开头声明的是的,谢谢!从您的第一个答案中获得,但感谢您的解释more@user2351722:很好,很高兴这有帮助!