绘制多个HTML画布时只绘制最后一个?

4
在我正在编写的应用程序中,有一个页面,在该页面上,我从数据库中加载多个base64编码的图像,并将它们放置在JavaScript数组中。这是通过EJS模板在服务器上发生的,因此当用户接收到HTML页面时,base64编码的图像已经存在(我已经检查过了)。
接下来,使用客户端的JavaScript循环遍历画布,然后使用相应的图像数据填充每个画布。但是,我得到了一些奇怪的行为。每次只有最后一个画布被填充。
for (var i = 1; i < 13; i++) {
    var ctx = document.getElementById('canvas-' + i).getContext('2d'),
        image = new Image();

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

在这段代码的上方(在同一作用域内)定义了images数组。如果我像这样执行代码,只有最后一个canvas(id为“canvas-12”)将被填充。如果我将for循环的结束条件降低到例如i < 11,只有id为“canvas-10”的canvas将被填充。

我是否遗漏了什么?

1个回答

12

看起来像是一个闭包问题;每次循环时,您都在更改onload函数中包含的ctx对象。您需要确保在使用闭包时不会在循环期间更新对象:

似乎是闭包问题;每次循环时,你都在改变onload函数中的ctx对象。你需要通过使用闭包来确保你不会在循环期间更新这些对象:

for (var i = 1; i < 13; i++) {
    var ctx = document.getElementById('canvas-' + i).getContext('2d'),
        image = new Image();
    (function(ctx, image) {
        image.onload = function() {
            ctx.drawImage(image, 0, 0);
        }
        image.src = images[(i - 1)];
    })(ctx, image);
}

注意:我没有测试过这个。


@SimonSarris 这个问题很可能已经有一个合适的“完全重复”的答案了。这是一个常见的问题。 - Evan Davis
谢谢,解决了我的问题!5分钟后我会接受你的答案 :) - lunanoko

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接