美文网首页微信小程序微信小程序开发微信小程序开发者
微信小程序image加载前显示默认占位图

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

作者: Quenice | 来源:发表于2018-09-23 11:32 被阅读12次

    在微信小程序中,我们使用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-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='https://www.neware.shop/demo/mobile/api/v1/public/image/download/201809051000165950' width="400rpx" height="200rpx" />
    

    相关文章

      网友评论

        本文标题:微信小程序image加载前显示默认占位图

        本文链接:https://www.haomeiwen.com/subject/udwfoftx.html