js圖片預加載的三種方法


預加載基本概念:當頁面打開圖片提前加載,並且緩存在用戶本地,需要用到時直接進行渲染;在瀏覽圖片較多的網頁(百度圖庫,淘寶京東等),可以有更好的用戶體驗;

一張圖片的預加載

1       var img=new Image();
2         img.addEventListener("load",loadHandler);
3         img.src="./img/1.jpg";
4         document.body.appendChild(img);
5         console.log(img.width);
6 
7         function loadHandler(e){
8             console.log(img.width);//當前圖片的原始寬度
9         }

上面代碼中,圖片還沒加載完成打印圖片的寬度時,圖片寬度為0;只有等圖片加載完成后並寫入DOM樹渲染后,才去觸發load事件的回調函數,才能打印出圖片的寬度;

加載多張圖片時,要提前在本地進行緩存,下面要講三種預加載多張圖片的例子:

第一種:load預加載

加載100張圖片,且圖片名為1.jpg~100.jpg(下同);

 1       var num=1;
 2         var list=[];
 3         loadImage();
 4         function loadImage(){
 5             var img=new Image();
 6             img.addEventListener("load",loadHandler);
 7             img.src="./img/"+num+".jpg";
 8         }
 9         function loadHandler(e){
10             list.push(this.cloneNode());//復制當前圖片元素
11             num++;
12             if(num>100){console.log(list);return;}
13             this.src="./img/"+num+".jpg"; //修改地址繼續后觸發load事件
14         }

上面代碼表示:

   1、創建一張圖片;
        2、給這個圖片增加事件偵聽load;
        3、加載完成后,將加載進來的圖片復制一個新的,放在數組中;
        4、修改num;如果num的值大於100停止執行,並且打印數組;
        5、給這個圖片的地址賦予一個新地址,因為改變圖片的地址就會重新觸發load,所以會繼續進入loadHandler函數,不斷加載,直到加載完成。
 
第二種:生成器函數實現預加載
 1 function loadImage(src){
 2         return new Promise(function(resolve,reject){
 3             let img=new Image();
 4             img.onload=function(){ 
 5                 resolve(img);//加載時執行resolve函數
 6             }
 7             img.onerror=function(){ 
 8                 reject(src+'這個地址錯誤');//拋出異常時執行reject函數
 9             }
10             img.src=src;
11         })
12     }
13     function* fn(){
14         for(let i=1;i<100;i++){
15             yield loadImage("./img/"+i+".jpg");
16         }
17     }
18     let s=fn();
19     let value=s.next().value; 
20     resume();
21     function resume(){
22         value.then(img=>{
23             console.log(img);//打印加載的圖片標簽
24             value=s.next().value;
25             if(value)resume();
26         });
27     }

以上代碼表示:

  1、執行生成器函數並且一次執行loadImage 函數;

  2、在Promise中創建圖片;

  3、判斷圖片是否可以加載,加載成功執行Promise的回調函數resolve;

  4、執行一次resume函數,並在函數里面執行Promise在resolved狀態下的函數

  5、反復執行s.next().value,直到全部圖片加載完成;

第三種:async/await預加載圖片

 1 function loadImage(src){
 2         let p=new Promise(function(resolve,reject){
 3             let img=new Image();
 4             img.onload=function(){//加載時執行resolve函數
 5                 resolve(img);
 6             }
 7             img.onerror=function(){
 8                 reject(src);
 9             }
10             img.src=src;
11         })
12         return p;
13     }
14     async function fn(){
15         let arr=[];
16         for(let i=3;i<80;i++){
17             await loadImage(`./img/${i}-.jpg`).then(img=>{
18                 arr.push(img);
19             });
20         }
21         return arr;
22     }
23     fn().then(list=>{
24         console.log(list);//打印圖片數組
25     })

這種方法是ES6的方法用到了async和await將異步轉換為阻塞式同步;

說明:

1、fn 這個函數使用async 表示這個函數是一個異步函數
2、這個函數中就可以使用await ,await作用就是讓異步變為同步等待,異步變成了阻塞式等待
3、當異步全部完成時,再繼續向后運行
4、async函數中的await后面只能跟的時Promise對象
5、async函數執行后返回的是一個Promise對象

以上就是三種預加載的方法,僅供參考;

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM