图片懒加载组建(简单版)

发布于 4 年前作者 mengxia4033 次浏览最后编辑 4 年前来自 share

话不多说 直接上效果图

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

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

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

我使用的方法 有两个

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

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

WXOPEN Club 内容图片WXOPEN Club 内容图片

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

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

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


js 页面

// js

/**
 * 监听元素是否出现在屏幕
 * @param { String } elName 所在的节点
 * @param { String } attr 需要获取的属性值
 *  {
 *      dataset    // 节点的dataset
 *      width      // 节点的宽度
 *      height     // 节点的高度
 *      scrollLeft // 节点的水平滚动位置
 *      scrollTop  // 节点的竖直滚动位置
 *      scrollX    // 节点 scroll-x 属性的当前值
 *      scrollY    // 节点 scroll-y 属性的当前值
 *
 *      // 此处返回指定要返回的样式名
 *      res.margin
 *      res.backgroundColor
 *      res.context    // 节点对应的 Context 对象
 * }
 * @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 回复
jxu
jxu1 楼2 个月前

先赞再说