图片懒加载组建(简单版)
发布于 3 年前 作者 mengxia 3714 次浏览 来自 分享

话不多说 直接上效果图

起因: 当时使用了官方的 image 里面的 lazy-load 的 属性, 发现在 net work 上, 并没有实际上的效果(我的图片设置的展示比例比较小, 且也做了分页的效果, 呈现出来的 数据差不多刚好两屏的样子), 而官方的文档上说的是 图片懒加载,在即将进入一定范围(上下三屏)时才开始加载, 这就很明显不是我想要的效果~

解决方法: 当时搜索了网上的信息, 无非都是通过数据源去做处理(要么统一在请求数据做处理, 还有就是在 滚动的时候去监听, 导致如果每个页面都需要使用的时候, 都需要引入改方法 或者 需要相同的数据格式, 我觉得很行), 再三思索下, 决定自己实现一个图片懒加载

我自己的解决思路(仅供参考)

我使用的方法 有两个

  1. 监听屏幕的滑动情况
  2. 元素是否出现在了屏幕上

实现以上的方法, 就分别需要用到两个 官方的 api

有了这两个方法, 就可以知道 我们需要的监听的图片是否有出现在图片的哪个位置了(需要特别指定位置)

wxml 页面(可以封装成一个图片的组建, 方便拓展)

// wxml
<image width="{{width}}" height="{{height}}" class="imgContent" src="{{show ? src : ''}}"/>


js 页面

// js

/**
 * 监听元素是否出现在屏幕
 * [@param](/user/param) { String } elName 所在的节点
 * [@param](/user/param) { String } attr 需要获取的属性值
 *  {
 *      dataset    // 节点的dataset
 *      width      // 节点的宽度
 *      height     // 节点的高度
 *      scrollLeft // 节点的水平滚动位置
 *      scrollTop  // 节点的竖直滚动位置
 *      scrollX    // 节点 scroll-x 属性的当前值
 *      scrollY    // 节点 scroll-y 属性的当前值
 *
 *      // 此处返回指定要返回的样式名
 *      res.margin
 *      res.backgroundColor
 *      res.context    // 节点对应的 Context 对象
 * }
 * [@param](/user/param) { Boolean } isComponent 是否在组建内使用
 * 
 * [@return](/user/return) {Function} 一个promise
 */

function listenEltoScreen({ elName = '', attr = '', value = '', isComponent = {} } = {}) {
    return new Promise((resolve) => {
        const query = !isComponent ? wx.createIntersectionObserver() : this.createIntersectionObserver()

        query.relativeToViewport({
            [attr]: value
        }).observe(elName, (res) => {
            resolve(res)
        })
    })
}

Component({
    /**
     * 组件的属性列表
     */
    properties: {
        // 图片链接
        src: {
            type: String,
            value: ''
        },
        width: {
            type: String,
            value: '100%'
        },
        height: {
            type: String,
            value: '100%'
        },
        // 是否触发懒加载(暂不支持动态修改 触发懒加载)
        lazy: {
            type: Boolean,
            value: true
        },
        // 触发懒加载的阀值
        threshold: {
            type: Number,
            value: 20
        },
        // 触发懒加载的方向
        direction: {
            type: String,
            value: 'bottom'
        }
    },

    /**
     * 组件的初始数据
     */
    data: {
        show: false
    },
    ready() {
        if (!this.data.lazy) return
        // 监听 元素是否有距离屏幕的情况
        listenEltoScreen.bind(this)({
            elName: '.imgContent',
            attr: this.data.direction,
            value: this.data.threshold,
            isComponent: true
        }).then(() => {
            console.log('触发了')
            this.setData({
                show: true
            })
        })
    }
})

以屏幕为一个检测点, 来以此判断 需要监听的元素是否有出现在屏幕上(实现原理), 实现的效果可以看顶部的视频, 个人的一个小懒加载, 可以适用在任何一个需要图片的页面, 也可以在此基础上拓展

代码片段: https://developers.weixin.qq.com/s/hXnoTpmE7RtD

(如果对你有帮助, 给个赞吧, 比较花了点时间研究)





1 回复

先赞再说

回到顶部