## 步骤
1.图片准备好原图的同比例的小图
原图:chapter1.png
模糊小图:hapter1_co.png
2.默认应用小图的地址
3.页面加载时去调用原图多大地址下载图片,下载完毕后替换成原图
## 实现
wxml文件
``` xml文件
<!-- 引入图片预加载组件 -->
<import src="../../components/img-loader/img-loader.wxml" />
<template is="img-loader" data="{{ imgLoadList }}"></template>
<image class="comicImg" mode="widthFix" src="{{comicImgSrc}}" />
```
js文件
``` js
//引入图片预加载组件
const ImgLoader = require('../../components/img-loader/img-loader.js')
data: {
//模糊小图
comicImgSrc: "https://www.fo.com/chapter1_co.jpg",
},
//生命周期函数
onLoad() {
//初始化图片预加载组件
this.imgLoader = new ImgLoader(this)
this.loadImage();
},
//加载成功后再替换
loadImage() {
this.imgLoader.load(this.data.comicImgSrc.replace('_co', ''), (err, data) => {
if (!err){
this.setData({
comicImgSrc: data.src
})
}
})
},
```
img-loader.js
```
/**
* 图片预加载组件
*
* @author HuiminLiu
*/
class ImgLoader {
/**
* 初始化方法,在页面的 onLoad 方法中调用,传入 Page 对象及图片加载完成的默认回调
*/
constructor(pageContext, defaultCallback) {
this.page = pageContext
this.defaultCallback = defaultCallback || function(){}
this.callbacks = {}
this.imgInfo = {}
this.page.data.imgLoadList = [] //下载队列
this.page._imgOnLoad = this._imgOnLoad.bind(this)
this.page._imgOnLoadError = this._imgOnLoadError.bind(this)
}
/**
* 加载图片
*
* @param {String} src 图片地址
* @param {Function} callback 加载完成后的回调(可选),第一个参数个错误信息,第二个为图片信息
*/
load(src, callback) {
if (!src) return;
let list = this.page.data.imgLoadList,
imgInfo = this.imgInfo[src]
if (callback)
this.callbacks[src] = callback
//已经加载成功过的,直接回调
if (imgInfo) {
this._runCallback(null, {
src: src,
width: imgInfo.width,
height: imgInfo.height
})
//新的未在下载队列中的
} else if (list.indexOf(src) == -1) {
list.push(src)
this.page.setData({ 'imgLoadList': list })
}
}
_imgOnLoad(ev) {
let src = ev.currentTarget.dataset.src,
width = ev.detail.width,
height = ev.detail.height
//记录已下载图片的尺寸信息
this.imgInfo[src] = { width, height }
this._removeFromLoadList(src)
this._runCallback(null, { src, width, height })
}
_imgOnLoadError(ev) {
let src = ev.currentTarget.dataset.src
this._removeFromLoadList(src)
this._runCallback('Loading failed', { src })
}
//将图片从下载队列中移除
_removeFromLoadList(src) {
let list = this.page.data.imgLoadList
list.splice(list.indexOf(src), 1)
this.page.setData({ 'imgLoadList': list })
}
//执行回调
_runCallback(err, data) {
let callback = this.callbacks[data.src] || this.defaultCallback
callback(err, data)
delete this.callbacks[data.src]
}
}
module.exports = ImgLoader
```
img-loader.wxml
```
<template name="img-loader">
<image wx:for="{{ imgLoadList }}" wx:key="*this" src="{{ item }}" data-src="{{ item }}" bindload="_imgOnLoad" binderror="_imgOnLoadError" style="width:0;height:0;opacity:0" />
</template>
```