Javascript pull-up and load data, the implementation in vue.js?

how to implement the pull-up load function in javascript and how to implement scroll snooping in vue.js?

there are several problems to be faced when doing pull-up loading

  1. how do I listen for scroll scroll bar scrolling events?
  2. how can I tell that scroll has scrolled to the bottom?
  3. handles the Height relationship between offset of scroll and documentElement

have examples: https://github.com/sunmengyua.

import Request from './request'

const Loadmore = {
    flag: true,
    view: null,
    opts: null,
    do: function (view, opts) {
        this.flag = true
        this.view = view
        this.view._Loadmore = view._Loadmore || {}
        this.opts = {
            url: opts.url,
            status: opts.status || 'init',
            params: opts.params || {},
            // 
            limit: opts.limit || 10,
            // 
            callbackFn: opts.callbackFn || function () {},
            // 
            completeFn: opts.completeFn || function () {},
            // 
            nodataFn: opts.nodataFn || function () {},
            // 
            errorFn: opts.errorFn || function () {}
        }
        if (this.opts.status === 'init') this.loadData()
        var type = opts.type || 'scroll'
        if (type === 'scroll') this.listenScroll()
    },
    loadData: function () {
        var view = this.view
        var opts = this.opts
        var status = {
            page: view._Loadmore.page || 0,
            offset: view._Loadmore.offset || 0,
            flag: (view._Loadmore.flag !== undefined)
                ? view._Loadmore.flag
                : true,
            destroyed: (view._Loadmore.destroyed !== undefined)
                ? view._Loadmore.destroyed
                : false
        }
        if (!this.flag) return
        this.flag = false
        if (status.flag && !status.destroyed) {
            Request({
                url: opts.url,
                params: {
                    ...opts.params,
                    page: status.page,
                    offset: status.offset,
                    limit: opts.limit
                }
            }).then((data) => {
                var list = data.data.list
                opts.callbackFn(list, data.data.page)
                view._Loadmore.page = status.page + 1
                view._Loadmore.offset = status.offset + opts.limit
                if ((list instanceof Array) && (list.length < opts.limit) && (list.length > 0)) {
                    view._Loadmore.flag = false
                    opts.completeFn({
                        page: status.page,
                        offset: status.offset,
                        list: list
                    })
                }
                if ((list === null) || !list.length) {
                    view._Loadmore.flag = false
                    if ((status.page === 0) || (status.offset === 0)) {
                        opts.nodataFn({
                            page: status.page,
                            offset: status.offset
                        })
                    }
                    opts.completeFn({
                        page: status.page,
                        offset: status.offset,
                        list: list
                    })
                }
                this.flag = true
            }).catch(() => {
                opts.errorFn({
                    page: status.page,
                    offset: status.offset
                })
                this.flag = true
            })
        }
    },
    clear: function () {
        this.view._Loadmore = {
            flag: true,
            page: 0,
            offset: 0
        }
    },
    listenScroll: function () {
        var t = null
        var pos = 0
        window.addEventListener('scroll', () => {
            if (t === null) {
                t = setTimeout(() => {
                    if (this.view._Loadmore.destroyed) return
                    var scrollY = window.scrollY
                    var scrollHeight = document.body.scrollHeight
                    var screenHeight = window.screen.availHeight
                    if (scrollY > pos) {
                        if (scrollHeight - scrollY < screenHeight + 20) this.loadData()
                    }
                    pos = scrollY
                    t = null
                }, 16)
            }
        })
    }
}

export default Loadmore

it just so happens that I wrote a simple one the day before yesterday for your reference.


you have ignored a problem, because scrolling may not occur 100% on window, but may happen in one of your div. If it happens in div, then binding scroll events to window will not take effect.


related codes

// 
new Vue({
    beforeMount: function() {
        // scroll
        window.addEventListener('scroll', this.handleScroll)
    },
    beforeDestroy () {
        window.removeEventListener('scroll', this.handleScroll)
    },
    data: {},
    mothods: {
        handleScroll: function() {
            // handle you scroll event
            
            // Yoffset    
            // max(window.pageYOffset) + window.innerHeight === document.documentElement.scrollHeight
            
            if (window.pageYOffset + window.innerHeight >= document.documentElement.scrollHeight) {
               //   
               // 
               // 
               // window.pageYOffset + window.innerHeight >= document.documentElement.scrollHeight - 20
            }
        }
    }
})
Menu