如何实现加载动画在所有图片加载完成后再收起,并让所有图片同时显示?
如何实现加载动画在所有图片加载完成后再收起,并让所有图片同时显示?
嗨,我来帮你搞定这个问题~你现在遇到的核心问题是:浏览器加载图片是异步操作,你设置完图片src后立刻收起加载动画,但这时候图片其实还在后台加载,所以会出现动画先消失、图片后冒出来的情况;而且你逐个设置图片src,它们的加载进度不一样,自然没法同时显示。
下面是具体的解决思路和代码调整方案:
核心思路
- 先预加载所有图片:不要直接把图片URL设置到页面的img元素上,而是先创建原生Image对象加载这些图片,确保所有图片都加载完成后再处理。
- 等待所有图片加载完成:用
Promise.all()监听所有图片的加载状态,只有当全部图片都加载成功(或处理加载失败的情况),再进行下一步。 - 统一显示图片+收起动画:所有图片准备好后,一次性把它们的
src设置到对应的页面元素上,然后再收起加载动画,这样就能实现图片同时显示,动画也不会提前消失。
调整后的代码
$w('#button8').onClick(() => calcular()); function calcular() { // 先展开加载动画 expand(`loadingAnimation`); query.find().then(res => { // 第一步:收集需要加载的图片URL(这里根据你的逻辑整理,注意原代码里的变量问题) const imageTasks = []; // 这里修正了原代码里未定义的item,以及字段名拼写差异(images/imagens) if (array[0]) { imageTasks.push({ element: '#image1', url: res[0].images }); } if (array[1]) { imageTasks.push({ element: '#image2', url: res[1].images }); } if (array[2]) { imageTasks.push({ element: '#image3', url: res[2].imagens }); } // 第二步:创建预加载的Promise数组 const loadPromises = imageTasks.map(task => { return new Promise((resolve, reject) => { const preloadImg = new Image(); preloadImg.src = task.url; // 图片加载成功,返回对应的元素和URL preloadImg.onload = () => resolve(task); // 图片加载失败,也需要捕获错误,避免动画一直挂着 preloadImg.onerror = () => reject(`图片加载失败:${task.url}`); }); }); // 第三步:等待所有图片加载完成 Promise.all(loadPromises) .then(loadedTasks => { // 统一设置所有图片的src,让它们同时显示 loadedTasks.forEach(task => { $w(task.element).src = task.url; }); // 所有图片都显示后,再收起加载动画 collapse(`loadingAnimation`); }) .catch(error => { console.error('加载出错:', error); // 即使加载失败,也要收起动画,避免一直阻塞 collapse(`loadingAnimation`); }); }) .catch(error => { console.error('查询数据出错:', error); collapse(`loadingAnimation`); }); }
几个关键细节提醒
- 原代码里有个小bug:循环中的
item变量没有定义,应该是res[i]?我在调整后的代码里直接根据你的array判断逻辑整理了图片任务,你可以根据实际数据结构再微调。 - 注意
images和imagens的拼写差异,确保后端返回的字段名和你代码里的一致,避免加载失败。 - 为什么要用原生Image预加载?因为有些平台的页面元素(比如Wix的$w元素)的加载事件监听可能不太方便,用原生Image能更可靠地捕捉到图片加载完成的时机。
备注:内容来源于stack exchange,提问作者gabrieljose
相关产品推荐
相关产品推荐

