首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >在JavaScript中等待镜像加载完成

在JavaScript中等待镜像加载完成
EN

Stack Overflow用户
提问于 2016-06-16 16:54:14
回答 3查看 18.8K关注 0票数 4

我正在用JavaScript加载图片。如下所示:

代码语言:javascript
复制
images[0]=new Image();
images[0].onload=function(){loaded++;console.log(loaded)};
images[0].src="assets/img/image.png";

当我查看日志时,我看到所有的图像都被很好地加载了,因为“已加载”变量的值随着每个已加载图像的增加而增加。

然而,我想停止任何进一步的行动,直到这个数量达到它的最大值,所以在设置图像之后,我放置了一段时间循环。

代码语言:javascript
复制
while(loaded<11){
    document.getElementById("test").innerHTML="Loading "+loaded+"/11";
    console.log(loaded);
}
//Some code here which should only run after everything has been loaded
//In other words: when the statement in the while cycle becomes false

然而,我的浏览器完全崩溃了,因为while似乎陷入了无限循环。当我检查日志时,我看到"0“被写了1000次,在那之后,数字从1到11 (这意味着图像实际上被加载了,但while并不关心它,崩溃的速度比它发生的速度更快)。

我认为我在这里尝试使用的方法不是解决这个问题的正确方法。

在加载站点所需的所有资产之前,我如何将所有内容都搁置?

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2016-06-16 17:04:29

就我个人而言,我讨厌使用while()...我认为最简单的方法是使用事件侦听器。

代码语言:javascript
复制
var img = new Image;
img.addEventListener("load", function () {

//Img loaded

});
img.src= e.target.result;
票数 7
EN

Stack Overflow用户

发布于 2019-05-28 19:42:35

使用promises和async函数,有一种很好的方法可以等待,直到加载完所有图像(没有回调,没有加载的图像计数):

代码语言:javascript
复制
async function loadImages(imageUrlArray) {
    const promiseArray = []; // create an array for promises
    const imageArray = []; // array for the images

    for (let imageUrl of imageUrlArray) {

        promiseArray.push(new Promise(resolve => {

            const img = new Image();
            // if you don't need to do anything when the image loads,
            // then you can just write img.onload = resolve;

            img.onload = function() {
                // do stuff with the image if necessary

                // resolve the promise, indicating that the image has been loaded
                resolve();
            };

            img.src = imageUrl;
            imageArray.push(img);
        }));
    }

    await Promise.all(promiseArray); // wait for all the images to be loaded
    console.log("all images loaded");
    return imageArray;
}

或者,您可以等待加载单个图像:

代码语言:javascript
复制
async function loadImage(imageUrl) {
    let img;
    const imageLoadPromise = new Promise(resolve => {
        img = new Image();
        img.onload = resolve;
        img.src = imageUrl;
    });

    await imageLoadPromise;
    console.log("image loaded");
    return img;
}

您可以这样使用它(使用promise链接):

代码语言:javascript
复制
loadImages(myImages).then(images => {
    // the loaded images are in the images array
})

或者在异步函数中:

代码语言:javascript
复制
const images = await loadImages(myImages);
票数 10
EN

Stack Overflow用户

发布于 2016-06-16 17:32:06

Javascript是单线程的。这意味着,如果添加一个事件侦听器,则该侦听器在当前执行完成之前不会运行。因此,如果您启动一个依赖事件来结束它的循环,它将永远不会发生,因为事件永远不会触发,因为当前的执行正在阻止它运行。此外,事件是异步放置在调用堆栈上的,因此,如果您的执行速度慢于事件触发的速率(在调用堆栈上放置一个调用),则还存在页面崩溃的风险。当间隔设置为比代码执行所需的时间更短时,这是使用setInterval时的常见错误。切勿使用setInterval。

请记住,Javascript不能同时做两件事。

处理资源监控加载的最好方法是使用setTimeout。

代码语言:javascript
复制
var allLoaded = false;
var imgCount = 0;  // this counts the loaded images
// list of images to load
const imageURLS =["a.jpg","b.jpg","c.jpg","d.jpg","e.jpg"];
// array of images
var images = [];

const onImageLoad = function(){ imgCount += 1; } // onload event
// loads an image an puts it on the image array
const loadImage = function(url){
    images.push(new Image());
    images[images.length-1].src = url
    images[images.length-1].onload = onImageLoad;
}
const waitForLoaded = function(){
    if(imgCount === images.length){
        allLoaded = true;   // flag that the image have loaded
    }else{
        // display  the progress here
        ...

        setTimeout(waitForLoaded,100); // try again in 100ms
    }
}

// create the images and set the URLS
imageURLS.forEach(loadImage);

setTimeout(waitForLoaded,100);  // monitor the image loading
票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/37854355

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档