为了账号安全,请及时绑定邮箱和手机立即绑定

微信小程序image加载前显示默认占位图

标签:
WebApp

在微信小程序中,我们使用Image组件来展示图片,图片源可以是本地资源,也可以是服务器资源。但是为了内容的动态展示,我们绝大多数情况下,会使用服务器资源来展现作为image的图片源。既然是服务器资源,那么就需要依赖于网络的快慢,如果在网络慢的情况下,image加载图片的过程可能会非常慢,所以在加载图片的过程中,如果不做处理,会出现一片空白的情况,直到图片加载完成,这是非常差的用户体验。

为了提高用户体验度,我们可以在图片加载完成之前,预先展示一张本地的默认占位图片,而不是显示空白。

小程序的image组件没有提供默认图片的属性,需要我们自己实现这个功能。

实现原理

微信小程序的image组件有两个属性:

属性名类型说明
binderrorHandleEvent当错误发生时,发布到 AppService 的事件名,事件对象event.detail = {errMsg: 'something wrong'}
bindloadHandleEvent当图片载入完毕时,发布到 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-defaultimage-real

在初始化的时候,我们显示的是image-default图片,同时,image-real也会一起加载,只不过,会通过css属性控制image-real不显示:

.before-load {  width: 0;  height: 0;  opacity: 0;
}

然后给image-real实现bindloadbinderror,在加载完成并成功后,把image-defaultwidthheight都置为空,这样image-default就不会再显示,同时让image-realwidhthheight恢复原始值,并把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;
}

注意:我这里为了简化,只实现了imagebindload而未实现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


点击查看更多内容
1人点赞

若觉得本文不错,就分享一下吧!

评论

作者其他优质文章

正在加载中
感谢您的支持,我会继续努力的~
扫码打赏,你说多少就多少
赞赏金额会直接到老师账户
支付方式
打开微信扫一扫,即可进行扫码打赏哦
今天注册有机会得

100积分直接送

付费专栏免费学

大额优惠券免费领

立即参与 放弃机会
意见反馈 帮助中心 APP下载
官方微信

举报

0/150
提交
取消