Javascript Internet Explorer 9有时在画布上绘制空白图像

Javascript Internet Explorer 9有时在画布上绘制空白图像,javascript,html5-canvas,Javascript,Html5 Canvas,我有一个web应用程序,它可以动态生成图像,然后使用画布在客户机上渲染(部分图像)-一般代码如下(简化) 在firefox和chrome中,这很好。在IE9(有时是IE10)中,这有时会导致空白图像。作为解决办法,我加入了 var width = ... var height = ... var img = new Image(); img.onload = function(){ var canvas = document.createElement("canvas"); canvas

我有一个web应用程序,它可以动态生成图像,然后使用画布在客户机上渲染(部分图像)-一般代码如下(简化)

在firefox和chrome中,这很好。在IE9(有时是IE10)中,这有时会导致空白图像。作为解决办法,我加入了

var width = ...
var height = ...
var img = new Image();
img.onload = function(){
  var canvas = document.createElement("canvas");
  canvas.setAttribute('width',width);  
  canvas.setAttribute('height',height);
  var context = canvas.getContext("2d");
  window.setTimeout(function(){
    context.drawImage(img,0,0,width,height,0,0,width,height);
  }, 10); // 10 millisecond delay here seems to give IE time to make sure the image is actually ready
}
img.src = ...
显然,随机延迟让我很紧张——我更愿意弄清楚为什么会发生这种情况。图像上是否有其他可能使用的事件类型/方法/属性?可能是由于图像/编码/传输方法发送的http头中存在某种原因造成的吗

由于在画布上绘制图像似乎会让新用户大吃一惊,因此搜索大多会产生开发人员在onload方法之前设置源代码的实例。我能找到的最接近的其他问题/回答是:

编辑:

我已经更新了示例,以在开始时包含宽度和高度定义

2013年4月29日编辑:

10毫秒的延迟并不总是足够的-我已经更改了代码来检查画布像素,以确定是否绘制了任何东西-这感觉像是一个丑陋的黑客-我想知道是否有更好的方法:

... snip - this is at the end of the image load callback..

if((navigator.appVersion.indexOf("MSIE")) >= 0){    

    function checkAndRedraw(){
        context.clearRect(0,0,width,height);
        context.drawImage(img, 0, 0, width, height);
        var imageData = context.getImageData(0, 0, width, height),
        data = imageData.data,
        len = data.length;

        for (var i = 0; i < len; i += 4){
            if(data[i] || data[i+1] || data[i+2]){
                scheduleRedraw = null; // prevent memory leak
                return; // A pixel contained some non empty value so something was drawn - done.
            }
        }

        scheduleRedraw();
    }
    var redrawHackTimeout;
    function scheduleRedraw(){
        window.clearTimeout(redrawHackTimeout);
        redrawHackTimeout = window.setTimeout(checkAndRedraw, 500);
    }

    scheduleRedraw();
}
//END IE9 Hack
。。。剪断-这是在图像加载回调的末尾。。
如果((navigator.appVersion.indexOf(“MSIE”))>=0{
函数checkAndRedraw(){
clearRect(0,0,宽度,高度);
绘图图像(img,0,0,宽度,高度);
var imageData=context.getImageData(0,0,宽度,高度),
data=imageData.data,
len=数据长度;
对于(变量i=0;i
var img=new Image();
img.src=。。。
img.onload=function(){//Set onload before after setting image source;)
var canvas=document.createElement(“canvas”);
canvas.setAttribute('width',width);
canvas.setAttribute('height',height);
var context=canvas.getContext(“2d”);
drawImage(this,0,0,宽度,高度,0,0,宽度,高度);
}

您必须设置
src
然后等待图像加载。

我在IE9中也有同样的问题,我必须做的也是:

            theImage = new Image();

    theImage.onload = function() {
        that = this;
        setTimeout(function() {
            that.onload2();
        }, 100);
    };


    theImage.onload2 = function(){
               #your old load function code
            }

            theImage.src = 'http://....';

我不明白为什么ie9在画布中还没有实际加载或“不可用”时触发加载图像函数。这让我毛骨悚然。

我想你的想法是相反的-如果你这样做,并且图像在缓存中,那么在附加事件处理程序之前,你的onload会被触发。@tofarr你可以使用
img.loaded
。检查它是否已加载,如果已加载,请执行您的代码。否则,攻击
onload
。奇怪的是,当调用onload方法时(使用console.log进行验证),img.loaded标志被设置为true-图像不会在没有延迟的情况下呈现到画布。我怀疑这是某种IE病毒,但如果是的话,我会认为它会发生在更多的人身上。这可能是一些使用分块传输编码发送图像的客户端错误——这就是我目前所能想到的。
var img = new Image();
img.src = ...
img.onload = function(){ // Set onload before after setting image source ;)
  var canvas = document.createElement("canvas");
  canvas.setAttribute('width',width);  
  canvas.setAttribute('height',height);
  var context = canvas.getContext("2d");
  context.drawImage(this,0,0,width,height,0,0,width,height);
}
            theImage = new Image();

    theImage.onload = function() {
        that = this;
        setTimeout(function() {
            that.onload2();
        }, 100);
    };


    theImage.onload2 = function(){
               #your old load function code
            }

            theImage.src = 'http://....';