Javascript 等待图像加载后再继续

Javascript 等待图像加载后再继续,javascript,image,asynchronous,canvas,load,Javascript,Image,Asynchronous,Canvas,Load,我正在使用JavaScript和canvas开发一个游戏。当游戏加载时,将使用的所有图像都将被缓存 观察资源时间线,我发现以下代码触发了一个异步请求: var sprite = new Image(); sprite.src = "sprites/sheet1.png"; 引擎将继续执行,最终开始绘制并播放关卡。在绘制第一帧后加载的图像可能由于剪切而永远不会出现(即不会变“脏”) 因此,我测试了以下内容: console.log("begin"); var sprite = new Image

我正在使用JavaScript和
canvas
开发一个游戏。当游戏加载时,将使用的所有图像都将被缓存

观察资源时间线,我发现以下代码触发了一个异步请求:

var sprite = new Image();
sprite.src = "sprites/sheet1.png";
引擎将继续执行,最终开始绘制并播放关卡。在绘制第一帧后加载的图像可能由于剪切而永远不会出现(即不会变“脏”)

因此,我测试了以下内容:

console.log("begin");
var sprite = new Image();
sprite.onload = function() { console.log('loaded!'); };
sprite.src = "sprites/sheet1.png";
console.log("end");
结果控制台输出的出现顺序如下:

  • 开始
  • end
  • 已加载
我正在寻找一种类似于
$.ajax
async:false
的方法来执行加载。不知道怎么。。。提前感谢您的帮助!
J.

您不应该进行任何同步(甚至不包括AJAX)调用,只需将代码放入适当的回调中:

function loadSprite(src, callback) {
    var sprite = new Image();
    sprite.onload = callback;
    sprite.src = src;
}
然后像这样使用它:

loadSprite('sprites/sheet1.png', function() {
    // code to be executed later
});
sprite.onload = function() {
    callback(whatever, args, you, have);
};
var loaders = [];
loaders.push(loadSprite('1.png'));
loaders.push(loadSprite('2.png'));
loaders.push(loadSprite('3.png'));
$.when.apply(null, loaders).done(function() {
    // callback when everything was loaded
});
如果要传递其他参数,可以这样做:

loadSprite('sprites/sheet1.png', function() {
    // code to be executed later
});
sprite.onload = function() {
    callback(whatever, args, you, have);
};
var loaders = [];
loaders.push(loadSprite('1.png'));
loaders.push(loadSprite('2.png'));
loaders.push(loadSprite('3.png'));
$.when.apply(null, loaders).done(function() {
    // callback when everything was loaded
});

如果要加载多个元素,需要等待所有元素完成,请考虑使用jQuery对象:

在加载精灵的函数中,可以执行以下操作:

loadSprite('sprites/sheet1.png', function() {
    // code to be executed later
});
sprite.onload = function() {
    callback(whatever, args, you, have);
};
var loaders = [];
loaders.push(loadSprite('1.png'));
loaders.push(loadSprite('2.png'));
loaders.push(loadSprite('3.png'));
$.when.apply(null, loaders).done(function() {
    // callback when everything was loaded
});

这个问题很老了,但是有一种方法可以做到这一点,而不需要jquery,也不需要冻结浏览器

在image1.onLoad中,使其加载image2
在image2.onLoad中,使其加载image3
在image3.onLoad中,使其加载image4
....
在imagen.onLoad中,使其加载主函数

我不确定这是否是最好的方法,但至少比冻结浏览器要好
您还可以加载所有音频文件或需要的任何其他资源,或需要运行的任何其他javascript


不需要冻结浏览器

画布有这个问题 我尝试了您的解决方案,但最简单有效的方法是:

function COLPOinitCanvas(imagesfile) {
    COLPOcanvas = document.getElementById("COLPOcanvas");
    COLPOctx = COLPOcanvas.getContext("2d");
    var imageObj = new Image();
    imageObj.src = imagesfile;
    imageObj.onload = function () {
        COLPOctx.drawImage(imageObj, 0, 0, COLPOcanvas.width, COLPOcanvas.height);
    };
}

谢谢你的回复。我忘了提到,这段代码是父函数调用的函数名“loadSprite(name)”的一部分。该父级从类似“for each sprite loadSprite(name)”的循环中调用它。我需要能够中断处理,使方法仅在加载图像时返回。你知道吗?如果不冻结浏览器,你就不能这么做。我会更新我的答案以显示正确的解决方案。嘿,谢谢,这很有趣。我一点也不知道那个被推迟的物体!这是一个很好的解释,说明了如何在没有已延迟对象(如$.ajax)的情况下使用延迟对象,而不与动画结合使用。非常有用,解释得很好-谢谢。这是我目前的做法(第一晚使用画布),但看起来很混乱。有更好的方法吗?我已经尝试为加载的资源设置真/假标志,并使用do/while循环,但除了此方法之外,我无法使任何东西正常工作。不确定。我的项目只需要一两个资源,所以我从来没有进入过整个资源加载场景。我相信有更好的方法可以做到这一点。祝你好运!:)我最终构建了一个自定义回调方法,该方法增加了一个资源计数器(并将其与资源数组的长度进行比较),如果它们是不同的值,则什么也不做;如果值匹配,则开始在画布上绘制(这意味着所有资源都已加载)。