为什么我的画布仅在刷新时加载?

时间:2013-08-02 14:07:55

标签: javascript html canvas

我有一个包含iframe的网页,iframe包含一个包含多达1,000个canvas元素的表。 canvas元素由iframe中定义的函数填充,该函数由父页面调用。该函数使用父页面中隐藏跨度中包含的base64数据URI迭代并填充每个画布。我已经阅读了一些关于类似问题的其他Stackoverflow帖子,但我已经尝试了最常用的建议(使用onload),但这似乎不起作用。我对html / javascript相当新鲜,所以我怀疑我是做最好的方式。我希望有人可以指导我如何确保所有画布元素在第一次加载时成功填充base64数据,所以我不需要多次刷新来获取缩略图?这是一些代码,它是我的html页面中非常修剪的代码。如果我要粘贴整个页面,可能会有太多太合理的处理。以下是我认为必不可少的演员。

我的onload调用我的函数填充画布,这是在包含iframe的主页上 -

<body onload="document.getElementById('framePage').contentWindow.fillCans();">

这是fillCans()函数,它包含在framePage iframe中(我可能应该将它移动到主html页面,但到目前为止这是脚本的演变方式......演变了哈哈)。如果您愿意,pgCnt元素包含“计数器”数字。它将定义要迭代的元素数量。当指定var c时,“can”+ i元素是画布。分配var imgSrc时,“span”+ i元素是父页面上包含基本64数据URI的隐藏span元素 -

function fillCans() {
    var cnt = document.getElementById("pgCnt").innerHTML;
    var cnt = cnt.split("-");
    var cnt1 = cnt[0];
    var cnt2 = cnt[1];
    for (var i=cnt1; i <= cnt2; i++) {
        var targ = "span"+i
        var c = document.getElementById("can"+i);
        var ctx = c.getContext("2d");
        ctx.fillStyle="#FFFFFF";
        ctx.fillRect(0,0,128,128);
        var image = new Image();
        var imgSrc = parent.document.getElementById("span"+i).innerHTML;
        imgSrc = imgSrc.split("*");
        image.src = imgSrc[0];
        ctx.drawImage(image,0,0);
    }

就像我说的那样,这将加载很好,firebug报告没有错误,但是所有的画布都是白色的,没有缩略图。当我点击刷新几次时,它们最终都会加载。我已经读过图像数据被异步加载但是我不确定是什么意思,我认为这意味着它不会被onload播放的规则所扮演?无论如何,感谢所有帮助stackoverflow社区。很高兴知道如何在第一页加载时成功加载这些缩略图。

在@ Sebastian的伟大建议之后,我能够让我的JavaScript正常运行。我正在粘贴新功能。因为它现在有效,万一有人遇到过类似的问题。我必须对绘制图像的函数实现onload调用,然后在IIFE中使用循环以确保每个缩略图都是使用正确迭代的数据绘制的。

function fillCans() {
var cnt = document.getElementById("pgCnt").innerHTML;
var cnt = cnt.split("-");
var cnt1 = cnt[0];
var cnt2 = cnt[1];
for (var i=cnt1; i <= cnt2; i++) {
    (function(iterable){
        var c = document.getElementById("can"+iterable);
        var ctx = c.getContext("2d");
        ctx.fillStyle="#FFFFFF";
        ctx.fillRect(0,0,128,128);
        var image = new Image();
        var imgSrc = parent.document.getElementById("span"+iterable).innerHTML;
        imgSrc = imgSrc.split("*");

        image.onload = function() {
            ctx.drawImage(image, 0, 0);
        };
        image.src = imgSrc[0];
    })(i);
}
}

1 个答案:

答案 0 :(得分:2)

你是对的,问题是必须首先加载图像,然后才能绘制它。 在您的情况下,在您致电

时未加载image
ctx.drawImage(image,0,0);

然而,稍后浏览器缓存了图像URL,并且在对源属性分配和drawImage调用的调用之间,浏览器已经从缓存中检索了图像。

要使其在任何情况下都有效,您需要等待图像加载:

  image.onload = function() {
    ctx.drawImage(image, 0, 0);
  };
  image.src = imgSrc[0];

请务必先注册回调,然后设置src

请参阅HTML Canvas DrawImage Tutorial