我有一个页面,将一堆图像加载到图库中,然后通过 vanilla JS 很好地重新排列它们。
为此,脚本必须等待所有图像均已加载(或超时)。更改页面设置(如用户设置过滤器)会导致 ajax 脚本重新加载或添加图像。它们作为预渲染的 HTML 页面发送。在这种情况下,当脚本立即运行时,图像尚未完全加载,缺少脚本的关键信息,例如宽度和高度。所以我需要等到我得到这个信息(=所有图像都已完全加载)。
这是我的方法背后的想法:我尝试通过类名获取 DOM 这部分中的所有图像,为每个图像添加一个承诺,以解决图像是否完全存在或短暂超时结束的情况。我想将所有这些承诺添加到一个数组中,然后使用 Promise.All() 检查该数组。这个解决了应该调用脚本来重新排列图片。
我以前从未直接使用过 Promise,而且我对 JS 也有点菜鸟。
这是我所拥有的:
function articleImageLoadingStatusChecker() {
var articleImages=document.getElementsByClassName("articleimage");
var listOfPromises = [];
articleImages.forEach(image => function(image) {
listOfPromises.push(
new Promise(resolve => {
image.addEventListener('load', () => { resolve(true); });
}));
});
return listOfPromises;
}
Promise.all(articleImageLoadingStatusChecker()).then(adjustImagesForGalleryView());
这是我的问题:
运行此程序时,我希望articleImages 是或至少表现得像一个数组。如果我 console.log 它,它会返回一个类似数组的数组,并且 .length 发送一个整数。但是,我收到了奇怪的错误: 未捕获类型错误:articleImages.forEach 不是函数
我不确定我是否正确实现了promise,所以实际上可以通过Promise.all()来检查。
我认为 addEventListener('load',..) 可能会产生误导,实际上并不是要求的正确状态。当调用图库脚本时,图像可能已被缓存或已加载,因此可能不会调用侦听器。如果图像完全加载,我宁愿有一些东西可以在任何情况下解决承诺。另外,我目前不知道如何添加一些内容来在 1 秒后解决承诺,以防图像无法加载。
目前,这根本不起作用,我没有主意了。 任何建议都非常受欢迎。谢谢你。
document.getElementsByClassName()
返回一个 HTMLCollection
类似数组的对象,它没有 forEach
方法。
要解决此问题,您可以使用
HTMLCollection
函数或使用 spread 语法 Array
将 Array.from()
转换为
...
。
Array.map()
是一个很好的补充,可以循环 articleImages
数组并为每个图像元素返回一个 Promise
。我建议您解决图像元素本身。这样您就可以稍后在承诺链中使用这些元素。
要在 1 秒后解决承诺,请在事件侦听器之前添加超时。在事件侦听器中,清除超时以防止每当
load
事件首次出现时运行超时回调。
在promise链中,只引用
adjustImagesForGalleryView
,不调用它(删除()
)。
function articleImageLoadingStatusChecker() {
const articleImages = Array.from(document.getElementsByClassName("articleimage"));
return articleImages.map(image =>
new Promise(resolve => {
let timeout = setTimeout(() => {
resolve(image);
}, 1000);
image.addEventListener('load', () => {
clearTimeout(timeout);
resolve(image);
});
})
);
}
Promise
.all(articleImageLoadingStatusChecker())
.then(adjustImagesForGalleryView);