ES6实现多张图片同时加载

xiaoxiao2021-02-28  29

前面已经更新了很多关于ES6的知识点,今天我们来综合的做一个小练习,让多张图片可以同时加载。

图片没有加载之前的状态是这样

HTML结构如下

<html lang="en"><head>    <meta charset="UTF-8">    <title>同时加载多张图片</title></head><body><div id='all'>    <img src="./images/load.gif" alt="" id="a1">    <img src="./images/load.gif" alt="" id="a2">    <img src="./images/load.gif" alt="" id="a3">    <img src="./images/load.gif" alt="" id="a4"></div><script src='jQ.js'></script></body></html>

给出的data数据如下

{"main": [{"id": "a1","url": "http://localhost:8088/images/a.jpg"},{"id": "a2","url": "http://localhost:8088/images/b.jpg"},{"id": "a3","url": "http://localhost:8088/images/c.jpg"},{"id": "a4","url": "http://localhost:8088/images/d.jpg"}]}

DOM结构中已经给出了加载中的路径 img标签页已经存在了,我们需要做的是,在img的src属性加载完成之后把src属性替换一下就OK了。

首先,我们需要利用ajax把数据先请求过来,,还记得应该怎么写吗?

用jquery写ajax只需要传递一个对象就可以了,而且很多参数都可以省略,我就直接用默认的get方式请求了,请求路径是我自己在后台定义的路由,你们可以自己定义,当ajax请求成功的时候打印一下data数据的值,看一下是否可以打印到。

$.ajax({url: '/data',    success: (data) => {var arr = JSON.parse(data).main;        console.log(arr);    }});

请求到的数据没有错,接下来我们开始思考,这个同时加载的功能到底利用什么可以实现呢?

好像还想不起来,先不要着急,还记得如何判断一张图片是否加载完成吗?

先new一个image,然后给image一个src属性,image有一个onload的方法,是图片加载完成之后触发,当图片加载完成之后,把页面上的src属性覆盖掉就可以了。

for(let i =0 ;i<arr.length;i++){let img = new Image();    img.src = arr[i].url;    img.onload = () => { img.src = $('#all img').eq(i)[0].src;    }}

看上去上面的代码好像是完成了要求,所有的图片都加载出来了,可是是同步加载的,如何实现异步加载呢?

还记得前两天学习的小P么?可以实现异步加载的ES6新增对象Promise,我们来复习一下基本的语法

new Promise((reslove, reject) => {if(){//如果条件满足,就调用reslove函数        reslove();    }}).then(reslove=>{//成功状态下执行的代码    })    .catch(reject=>{报错或者失败状态下执行的代码 });

我们尝试一下利用Promise来改写上面的图片加载代码

先创建一个promise实例,代码的主体部分应该一样,先new一个image,然后给图片一个src属性

new Promise((reslove, reject) => {let img = new Image();    img.src = url;}).then(reslove=>{}).catch(reject=>{});

小p里面有个特别重要的判断条件,决定了小p以后的人生,可是这个判断条件该如何写呢?满足什么情况下才会成功呢?

当图片加载完成之后,就是这个条件,可这个条件该如何写呢?当图片加载完成之后改变小p的状态不就好了,代码如下:

new Promise((reslove, reject) => {let img = new Image();    img.src = url;    img.οnlοad=()=>{ reslove();    }}).then(reslove=>{}).catch(reject=>{});

当图片加载完成之后,调用小p成功状态下的回调函数,回调函数里面该写什么呢?

当图片加载完成之后,肯定是要替换页面中的路径,把图片呈现在用户的面前了,所以回调函数里面的代码应该是

$('#all img').eq(1).src=url;

url是我们需要用的参数,通过调用的时候把参数传递过来

new Promise((reslove, reject) => {let img = new Image();    img.src = url;    img.οnlοad=()=>{ reslove(url);    }}).then(url=>{$('#all img').eq(1)[0].src=url;}).catch(reject=>{});

eq后面的参数我们不能写成死的,可是写很多遍又太麻烦,所以我们现在需要一个循环,把url地址和I下标传给小p

for(let i=0;i<arr.length;i++){new Promise((reslove, reject) => {let img = new Image();        img.src = arr[i].url;        img.οnlοad=()=>{ reslove(arr[i].url);        } }).then(url=>{$('#all img').eq(i)[0].src=url;    }).catch(reject=>{});}

这次的代码看上去没什么问题了,我们来运行一下试试:

图片都加载出来了,这样就算结束了吗?

再仔细想想,有没有更好的办法,我们之前学过的一个方法,可以控制一个集合的promise实例。

Promise.all();

周六只是简单的跟大家提了一下,今天来介绍一下这个方法的主要功能,当他的状态变为成功的时候,会触发reslove的回调函数,回调函数里面的参数就是所有集合里面的小小p的成功函数参数的集合,也是一个数组,理解起来有一点点抽象对不对?我们画一张图来看看

上面的图片有一点点抽象,大家原谅一下我们这个灵魂画手。

我们换成代码表示就是

var arr=[1,2,3,4];var pAll=[];for (let i=0;i<arr.length;i++){let p= new Promise((reslove,reject)=>{reslove(arr[i]);    });    pAll.push(p);};Promise.all(pAll).then(reslove=>{console.log(reslove); console.log(arr);});

arr数组里面每一项的值分别是每个小promise的参数,Promise.all成功函数的返回值刚好就是arr里面的每一项,符合了上面的一一对应。

我们尝试用这个方法来改写一下上面的代码,

那么这次就需要先let一个空数组,把每一个图片的promise先放在里面了;

let all=[];

我们先来封装一个函数来创建promise实例

   function addPromise(url) {return new Promise((reslove, reject) => {let img = new Image();        img.src = url;        img.onload = () => {reslove(url);        } }) };

之后利用刚刚所学的Promise.all来进行改写上面的代码

for (let i = 0; i < arr.length; i++) {arr.push(addPromise(arr[i].url));};Promise.all(arr).then(reslove => {for (let i = 0; i < reslove.length; i++) { $('#all img').eq(i)[0].src = reslove[i];}

到这里为止,我们今天的任务就完成了,看一下整体的代码

$.ajax({url: '/data',    success: (data) => {var arr = JSON.parse(data).main;    function addPromise(url) {return new Promise((reslove, reject) => {let img = new Image();        img.src = url;        img.onload = () => {reslove(url);        } }) };    for (let i = 0; i < arr.length; i++) {arr.push(addPromise(arr[i].url)); }; Promise.all(arr).then(reslove => {for (let i = 0; i < reslove.length; i++) { $('#all img').eq(i)[0].src = reslove[i]; } }); }});

先利用ajax进行参数的请求,之后用函数封装一个构造Promise的方法,promise里面判断图片是否加载完成,最后循环调用函数,利用Promise.all方法整体操作替换src路径。

今天算是又重新整理一遍了,希望我写的明白一点了,点击原文链接即可获得《css世界》电子版,也算是大家的一点小福利吧。

转载请注明原文地址: https://www.6miu.com/read-2626791.html

最新回复(0)