drawImage()不显示图片

1、问题源码

<p>要使用的图像:</p>
<img id="tulip" src="/i/eg_tulip.jpg" alt="The Tulip" />

<p>画布:</p>
<canvas id="myCanvas" width="500" height="300" style="border:1px solid #d3d3d3;background:#ffffff;">
Your browser does not support the HTML5 canvas tag.
</canvas>

<script>

var c=document.getElementById("myCanvas");
var ctx=c.getContext("2d");
var img=document.getElementById("tulip");
ctx.drawImage(img,10,10);

</script>

2、解决办法

ctx.drawImage(img,10,10);

外面套一层:

img.onload=function(){
	ctx.drawImage(img,10,10);
}

3、原因分析

图片的加载是异步的,它会在自己后面的非异步代码执行完之后,再开始执行自己

异步猛一看有点并发的感觉,其实还是排队,且还是排的原来那条队,时间并没有被节省,只不过它会在轮到自己时,放弃自己的位置,主动站到非异步的代码队尾,非异步的都执行完再轮到自己时,才开始执行自己的,它后面其他的异步对象也是如此,不过后面异步的对象会等前面的异步执行了之后再执行,不过不会等待前面的异步执行完才执行。有点Gentleman的赶脚!

js中所有事件都是异步的,onload也是,onload的异步在图片异步之后,所以onload会在图片加载之后执行,同时onload除了异步之外,它还是个事件,也就是图片加载了之后才会触发,所以使用onload是百分百可以看到图片

同时如果不使用onload,使用

setTimeout(function(){
	ctx.drawImage(img,10,10);
},0);

也会看到图片被绘制出来,不过不是稳定的,偶尔看不到。原因就是

setTimeout

制造了一个异步,即使等待时间是0,这就意味着它成了一个图片加载异步之后的一个异步,图片加载先执行,它后执行,假如图片加载的快,它就绘制成功,慢了,它就失败。如果没有了

setTimeout

就百分百失败,因为绘制图片的代码所在的子队列在图片异步之前,图片会等到它执行完了,才刚刚开始自己的加载工作

PS

1、火狐似乎是个特例,它不用那些麻烦事,直接w3school拷贝下来的实例代码,刷新下就可以正常访问了,这是为啥?

2、w3school上拷贝的代码虽然本地不能绘制成功,可是在线,在它的实例执行页面看效果确实正常的,这怎么解释呢?

有路过的大神,还请赐教~

你可能感兴趣的:(drawImage()不显示图片)