我正在使用JavaScript加载图片。像这样:
images[0]=new Image();
images[0].onload=function(){loaded++;console.log(loaded)};
images[0].src="assets/img/image.png";
当我查看日志时,我看到所有图像都被很好地加载,因为"加载了#34;变量随着每个加载的图像而增加。
但是我想停止执行任何进一步的操作,直到这个数量达到它的最大值,所以在设置图像之后,我放置了一段时间。
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似乎陷入无限循环。当我查看日志时,我看到&#34; 0&#34;写了1000次,之后,数字从1到11(这意味着图像实际上已经加载了,但是while并不关心它,并且崩溃的速度比它可能发生得快)。
我相信我试图在这里使用的方法不是解决此问题的正确方法。
如果在加载网站所需的每项资产之前,我怎么能暂停一切?
答案 0 :(得分:3)
我个人讨厌使用while()......我认为最简单的方法就是使用事件监听器。
var img = new Image;
img.addEventListener("load", function () {
//Img loaded
});
img.src= e.target.result;
答案 1 :(得分:2)
Javascript是单线程的。这意味着如果添加一个事件侦听器,该侦听器将在当前执行完成之前不会运行。因此,如果您启动一个依赖于事件来结束它的循环,它将永远不会发生,因为事件永远不会触发,因为当前执行阻止它运行。此外,事件异步放置在调用堆栈上,因此如果执行速度低于事件触发速率(在调用堆栈上调用),则还会导致页面崩溃。当间隔设置为比执行代码所花费的时间更短时,使用setInterval时常见错误。永远不要使用setInterval。
请记住Javascript不能同时做两件事。
处理资源监控加载的最佳方法是使用setTimeout。
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 :(得分:1)
使用Promise和异步功能,有一种不错的方法来等待所有图像加载完毕(没有回调,也没有加载计数的图像):
async function loadImages(imageUrlArray) {
const promiseArray = []; // create an array for promises
const imageArray = []; // array for the images
for (let imageUrl of imageUrlArray) {
let resolveFunction; // this function needs to be called to resolve the promise
const imageLoadPromise = new Promise(resolve => {
resolveFunction = resolve; // set the resolve function here
});
promiseArray.push(imageLoadPromise); // store the promise
const img = new Image();
// if you don't need to do anything when the image loads, then you can just write
// img.onload = resolveFunction;
img.onload = function() {
// call the resolve function, indicating that the image has been loaded
resolveFunction();
// do stuff with the image if necessary
};
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;
}
或者您可以等待单个图像加载:
async function loadImage(imageUrl) {
let resolveFunction;
const imageLoadPromise = new Promise(resolve => {
resolveFunction = resolve;
});
const img = new Image();
img.onload = resolveFunction;
img.src = imageUrl;
await imageLoadPromise;
// console.log("image loaded");
return img;
}
您可以这样使用它(使用诺言链):
loadImages(myImages).then(images => {
// the loaded images are in the images array
})
或在异步函数中:
const images = await loadImages(myImages);