Javascript 在继续之前等待图像加载

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/8645143/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-24 06:53:55  来源:igfitidea点击:

Wait for image to be loaded before going on

javascriptimageasynchronouscanvasload

提问by Jem

I'm developing a game using JavaScript and canvas. As the game loads, all images that will be used are being cached.

我正在使用 JavaScript 和canvas. 随着游戏加载,所有将使用的图像都被缓存。

Observing the resource timeline, I see that the following code triggers an asynchronous request:

观察资源时间线,看​​到如下代码触发了一个异步请求:

var sprite = new Image();
sprite.src = "sprites/sheet1.png";

The engine will keep executing, eventually beginning to draw and play the level. Images that are loaded after the first frame is painted might never appear due to clipping (i.e. not getting "dirty").

引擎将继续执行,最终开始绘制和播放关卡。在绘制第一帧之后加载的图像可能永远不会出现,因为剪裁(即没有变得“脏”)。

So I tested the following:

所以我测试了以下内容:

console.log("begin");
var sprite = new Image();
sprite.onload = function() { console.log('loaded!'); };
sprite.src = "sprites/sheet1.png";
console.log("end");

The resulting console outputs in the order they occur are:

结果控制台输出按它们出现的顺序是:

  • begin
  • end
  • loaded!
  • begin
  • end
  • loaded!

I'm looking for a similar way to $.ajaxwith async: falseto perform the loading. Can't figure out how... thanks in advance for you help! J.

我正在寻找$.ajax与 with类似的方法async: false来执行加载。无法弄清楚如何......提前感谢您的帮助!J。

回答by ThiefMaster

You shouldn't make anything synchronous (not even AJAX) calls but instead simply put your code in the appropriate callback:

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

function loadSprite(src, callback) {
    var sprite = new Image();
    sprite.onload = callback;
    sprite.src = src;
}

Then use it like this:

然后像这样使用它:

loadSprite('sprites/sheet1.png', function() {
    // code to be executed later
});

If you want to pass additional arguments, you can do it like this:

如果你想传递额外的参数,你可以这样做:

sprite.onload = function() {
    callback(whatever, args, you, have);
};


If you want to load multiple elements and need to wait for all of them to finish, consider using the jQuery deferredobject:

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

function loadSprite(src) {
    var deferred = $.Deferred();
    var sprite = new Image();
    sprite.onload = function() {
        deferred.resolve();
    };
    sprite.src = src;
    return deferred.promise();
}

In the function loading the sprites, you do something like this:

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

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

http://api.jquery.com/jQuery.when/

http://api.jquery.com/jQuery.when/

回答by Interpolate

This question is old, but there is a way to do this without requiring jquery, OR freezing the browser.

这个问题很老了,但是有一种方法可以在不需要 jquery 或冻结浏览器的情况下做到这一点。

In image1.onLoad, make it load image2.
In image2.onLoad, make it load image3.
In image3.onLoad, make it load image4.
....
In imagen.onLoad make it load your main function.

在 image1.onLoad 中,让它加载 image2。
在 image2.onLoad 中,让它加载 image3。
在 image3.onLoad 中,让它加载 image4。
....
在图像n.onLoad 让它加载你的主要功能。

I'm not sure if this is the entirely BEST way to do it, but it's better than freezing the browser, at least.
You are able to also load all of your audio files or whatever other resources you need, or any other javascript you need to run.

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

Freezing the browser is not required

不需要冻结浏览器

回答by ettore ct

I've this problem with canvas i tried your solution but a best and simple way that works is:

我在画布上遇到了这个问题,我尝试了您的解决方案,但最好且最简单的方法是:

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