zoukankan      html  css  js  c++  java
  • 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对象

    以上就是三种预加载的方法,仅供参考;

     
  • 相关阅读:
    各种小知识
    基础技能
    st表
    有理数取余
    FFT加速高精度乘法
    unique
    离散化
    线段树复杂度分析
    楼房重建
    电脑装系统常用方法
  • 原文地址:https://www.cnblogs.com/cpfblogs/p/12776434.html
Copyright © 2011-2022 走看看