为什么我的画布仅在刷新时加载? [英] Why do my canvases only load on refresh?

查看:50
本文介绍了为什么我的画布仅在刷新时加载?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个网页,其中包含一个iframe,该iframe包含一个表格,其中最多包含1,000个画布元素.canvas元素由iframe中定义的函数填充,该函数由父页面调用.该函数迭代并使用父页面的隐藏跨度中包含的base64数据URI填充每个画布.我已经阅读了其他一些关于类似问题的Stackoverflow帖子,但是我已经尝试了最常用的建议(使用onload),但这似乎行不通.我对html/javascript相当陌生,所以我怀疑我正在以最好的方式做事.我希望有人能指导我如何确保所有画布元素在首次加载时均成功用base64数据填充,因此我无需刷新多次即可获得缩略图?这是一些代码,它是从我的html页面整理的代码.如果要粘贴整个页面,那么处理起来可能有点太过分了.我认为这是至关重要的角色.

I have a web page which contains an iframe, the iframe contains a table which contains up to 1,000 canvas elements. The canvas elements are filled by a function defined in the iframe, which is called by the parent page. The function iterates and fills each canvas with a base64 data URI contained in a hidden span in the parent page. I have read a few other Stackoverflow posts regarding similar issues but I have already tried the most commonly used suggestion (using onload) and that does not seem to work. I am fairly fresh to html/javascript so I doubt I am doing things the best way. I was hoping someone could guide me on how to assure that all the canvas elements are successfully filled with the base64 data on the first load so I don't need to refresh multiple times to get me thumbnails? Here is some code, it is VERY trimmed up code from my html page. If I were to paste the entire page, it might be a bit too much too handle sensibly. Here is what I believe to be the essential actors.

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

My onload call to my function which fills the canvases, this is on the main page which contains the iframe -

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

这是fillCans()函数,该函数包含在framePage iframe中(我可能应该将其移到主要的html页面,但是到目前为止,这是脚本的工作方式……发展了哈哈).pgCnt元素将包含计数器"数字.它将定义要迭代的元素.分配var c后,"can" + i元素即为画布.分配var imgSrc后,"span" + i元素是父页面上的隐藏span元素,其中包含基础64个数据URI-

Here is the fillCans() function which is contained within the framePage iframe (I probably should move this to the main html page, but so far this is how the script has... evolved haha). pgCnt element contains the "counter" numbers if you will. It will defines how many elements to iterate through. When var c is assigned, the "can"+i elements are the canvases. When var imgSrc is assigned, the "span"+i elements are the hidden span elements on the parent page which contain the base 64 data URIs -

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社区的帮助.知道如何使这些缩略图在第一页加载时成功加载将是很棒的.

Like I said, this will load fine, firebug reports no errors, however all the canvases are white with no thumbnails. When I hit refresh a few times they all finally load. I've read that the image data is asynchronously loaded but I am not certain to as what that means, I assume it means it doesn't play by the rules that onload plays by? Anyways as usual, thanks for all the help stackoverflow community. It will be great to know how to get these thumbnails to load successfully on the first page load.

在@Sebastian提出了很好的建议之后,我得以使我的JavaScript正常运行.我正在粘贴新功能.由于现在有效,以防万一有人遇到类似问题.我必须对绘制图像的函数实施onload调用,然后在IIFE中利用循环来确保每个缩略图都绘制有正确的迭代数据.

After @Sebastian's great suggestions I was able to get my JavaScript functioning as it should. I am pasting in the new function. As it works now, in case anyone ever comes across a similar issue. I had to implement an onload call to a function which drew the image, and then utilize in IIFE for loop to insure that each thumbnail was drawn with correctly iterated data.

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);
}
}

推荐答案

是的,问题是必须首先加载图像,然后才能绘制图像.就您而言,在调用

You are right, the problem is that the image has to be loaded first, before you can draw it. In your case image is not loaded at the time you call

ctx.drawImage(image,0,0);

但是,稍后在浏览器上缓存了图像URL,并且在调用source属性的调用和 drawImage 调用之间,浏览器已经从缓存中检索了图像.

However later on the browser has cached the image URL and in between the calls to the assignment of the source property and the drawImage call the browser has already retrieved the image from the cache.

要使其在任何情况下都能正常工作,您需要等待图像加载:

To make it work in any case, you need to wait for the image to load:

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

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

Be sure to first register the callback and then set the src.

请参见 HTML画布DrawImage教程

这篇关于为什么我的画布仅在刷新时加载?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆