在微信小程序中,我们使用Image
组件来展示图片,图片源可以是本地资源,也可以是服务器资源。但是为了内容的动态展示,我们绝大多数情况下,会使用服务器资源来展现作为image
的图片源。既然是服务器资源,那么就需要依赖于网络的快慢,如果在网络慢的情况下,image
加载图片的过程可能会非常慢,所以在加载图片的过程中,如果不做处理,会出现一片空白的情况,直到图片加载完成,这是非常差的用户体验。
为了提高用户体验度,我们可以在图片加载完成之前,预先展示一张本地的默认占位图片,而不是显示空白。
小程序的image
组件没有提供默认图片的属性,需要我们自己实现这个功能。
实现原理
微信小程序的image
组件有两个属性:
属性名 | 类型 | 说明 |
---|---|---|
binderror | HandleEvent | 当错误发生时,发布到 AppService 的事件名,事件对象event.detail = {errMsg: 'something wrong'} |
bindload | HandleEvent | 当图片载入完毕时,发布到 AppService 的事件名,事件对象event.detail = {height:'图片高度px', width:'图片宽度px'} |
我们可以实现这两个事件:
实现
bindload
,在图片未加载完成时,显示占位图,一旦加载完成,马上隐藏占位图,显示真正的业务图片实现
binderror
,在图片加载错误时,显示占位图。
具体实现
新建一个小程序项目
打开微信开发者工具,新建一个小程序项目Demo
,删除无用代码
自定义组件
在实际开发中,在多个地方都会用到image
组件,如果在每个使用的地方都去实现一遍占位图的功能,不仅会增加代码量,而且也增加维护量,所以,我们可以把这些逻辑,封装为一个自定义组件,这里我们取名为image-loader
,然后任何用到的地方,直接用image-loader
去代替image
就可以了。
新建image-loader
使用微信开发工具新建一个自定义组件,并位于项目的目录components
中,这个大家使用过微信开发工具的肯定都会操作,这里就不在赘述。然后找到一张占位图,放到项目的images
目录下,完成之后
现在项目的目录结构:
$ tree . ├── app.js ├── app.json ├── app.wxss ├── components │ ├── image-loader.js │ ├── image-loader.json │ ├── image-loader.wxml │ └── image-loader.wxss ├── images │ └── placeholder800x400.png ├── pages │ └── index │ ├── index.js │ ├── index.json │ ├── index.wxml │ └── index.wxss └── project.config.json
实现image-loader
我们在image-loader
中,加入两个image
,一个image
用于加载默认图片,一个image
用于加载真正的图片。为了描述方便,我们把这两个image
称为image-default
和image-real
在初始化的时候,我们显示的是image-default
图片,同时,image-real
也会一起加载,只不过,会通过css
属性控制image-real
不显示:
.before-load { width: 0; height: 0; opacity: 0; }
然后给image-real
实现bindload
和binderror
,在加载完成并成功后,把image-default
的width
和height
都置为空,这样image-default
就不会再显示,同时让image-real
的widhth
和height
恢复原始值,并把opcity
置为1
。
下面贴出所有代码
image-loader.js
/** * 图片预加载组件 */Component({ properties: { //默认图片 defaultImage: String, //原始图片 originalImage: String, width: String, height: String, //图片剪裁mode,同Image组件的mode mode: String }, data: { finishLoadFlag: false }, methods: { finishLoad: function (e) { this.setData({ finishLoadFlag: true }) } } })
image-loader.jsong
{ "component": true, "usingComponents": {} }
image-loader.wxml
<image wx:if='{{!finishLoadFlag}}' mode='{{mode}}' src='{{defaultImage}}' style='{{width ? "width:" + width : ""}};{{height ? "height:" + height : ""}}' /> <image mode='{{mode}}' class='{{finishLoadFlag ? "" : "before-load"}}' src='{{originalImage}}' bindload='finishLoad' style='{{finishLoadFlag && width ? "width:" + width : ""}};{{finishLoadFlag && height ? "height:" + height : ""}}' />
image-loader.wxss
.before-load { width: 0; height: 0; opacity: 0; }
注意:我这里为了简化,只实现了
image
的bindload
而未实现binderror
。
测试
最后,我们修改pages/index
页面代码测试一下
启用插件
index.json
{ "usingComponents": { "image-loader": "/components/image-loader" } }
测试代码:
index.wxml
<image-loader default-image='../images/placeholder800x400.png' mode='widthFix' original-image='
作者:Quenice
链接:https://www.jianshu.com/p/2ddbdb6c6b6d
共同学习,写下你的评论
评论加载中...
作者其他优质文章