遇到一个面试题,把其中一部分功能单独封装了一个批量加载图片的class。
斗胆擅自加了一点功能,
1、 配置第一批同时发起load的图片数量(默认5张)。
2、无论成败,每结束一张图片加载自动加载下一张。
3、每张图片右侧实时展示目前加载状态(ready,pendding,success,failed)。
代码还在完善中,先上代码后续更新:
class ImgsLoader { constructor(srcs = [], BATCH_QUANTITY = 10) { this.TOTAL_QUANTITY = srcs.length; this.BATCH_QUANTITY = BATCH_QUANTITY; this.IMG_INFOS = srcs.map((src, index) => { this.PROGRESS = 0; const dom = document.createElement('div'); dom.id = `innerItem-${index}`; const progressText = document.createElement('span'); progressText.id = `innerItemText-${index}`; progressText.innerText = "等待加载中..."; const img = new Image(); dom.appendChild(img); dom.appendChild(progressText); const imgInfo = { src, index, status: 0, // 0: ready,1: pendding,2:success,3:failed progress: 0, progressText, dom, img } return imgInfo; }); } mount(selector) { this.SELECTOR = selector; if (!this.SELECTOR){ return; } this.IMG_INFOS.forEach(({dom}) => document.querySelector(this.SELECTOR)?.appendChild?.(dom)); this.IMG_INFOS.slice(0, this.BATCH_QUANTITY)?.forEach?.(imgInfo => { this.load(imgInfo); }); } TOTAL_QUANTITY = 0; IMG_INFOS = []; SUCCESS_LIST = []; FAILED_LIST = []; BATCH_QUANTITY = 10; CURRENT_INDEX = 0; PROGRESS = 0; SELECTOR = null; async load(imgInfo) { return new Promise((resolve, reject) => { const img = imgInfo.img; imgInfo.status = 1; img.onload = () => { img.onload = null; imgInfo.status = 2; // 0: ready,1: pendding,2:success,3:failed } img.onerror = () => { img.onerror = null; img.onabort = null; imgInfo.status = 3; // 0: ready,1: pendding,2:success,3:failed } img.onabort = img.onerror img.src = imgInfo.src; this.recursiveCheckStatus(imgInfo, resolve, reject); }); } recursiveCheckStatus(imgInfo, resolve, reject) { requestAnimationFrame(() => { // 0: ready,1: pendding,2:success,3:failed if (imgInfo.status === 1) { imgInfo.progress = imgInfo.progress < 100 ? (imgInfo.progress + 1) : imgInfo.progress; imgInfo.progressText.innerText = `加载进度${imgInfo.progress}%` setTimeout(this.recursiveCheckStatus.bind(this, imgInfo, resolve, reject), 500); return; } if (imgInfo.status === 2) { imgInfo.progressText.innerText = "加载成功" if ((this.CURRENT_INDEX + 1) < this.TOTAL_QUANTITY) { this.CURRENT_INDEX++; const nextInfo = this.IMG_INFOS.find(({index}) => index === this.CURRENT_INDEX); nextInfo && this.load(nextInfo); } this.PROGRESS = this.CURRENT_INDEX + 1; resolve?.(); return; } if (imgInfo.status === 3) { imgInfo.progressText.innerText = "加载失败" if ((this.CURRENT_INDEX + 1) < this.TOTAL_QUANTITY) { this.CURRENT_INDEX++; const nextInfo = this.IMG_INFOS.find(({index}) => index === this.CURRENT_INDEX); nextInfo && this.load(nextInfo); } this.PROGRESS = this.CURRENT_INDEX + 1; reject?.(); } }) } } // 使用: const loader = new ImgsLoader(['https://img1.baidu.com/it/u=754329322,2526521035&fm=253&fmt=auto&app=138&f=JPEG?w=889&h=500', 'https://img0.baidu.com/it/u=3749906677,2827831142&…p;fmt=auto&app=120&f=JPEG?w=800&h=500', 'https://img2.baidu.com/it/u=3200016476,4256473359&fm=253&fmt=auto&app=138&f=PNG?w=360&h=200'], 2) loader.mount("#list");
标签:INDEX,封装,批量,img,CURRENT,QUANTITY,imgInfo,加载 From: https://www.cnblogs.com/zhuxiaoweb/p/18352968