懒加载 下拉刷新 上拉加载

88 阅读1分钟
const h = document.documentElement.clientHeight

function throttle(fn, delay = 200) {
    let timer = null;
    return function () {
        if (timer) return;
        timer = setTimeout(() => {
            fn.apply(this, arguments);
            timer = null;
        }, delay);
    }
}

function isTop() {
    var t = document.documentElement.scrollTop || document.body.scrollTop;
    return t === 0 ? true : false;
}

const isVisible = (element) => {
    let rect = element.getBoundingClientRect();
    return rect.top < h && rect.bottom > 0;
}

const isVisible50 = (element) => {
    const elHeight = element.offsetHeight
    let rect = element.getBoundingClientRect();
    return rect.top < h - (elHeight + 64) * 0.5;
}

const lazyLoadImg = (imgArr = []) => {
    const len = imgArr.length

    for (let i = 0; i < len; i++) {
        let img = imgArr[i];
        const url = img.dataset['url']
        if (isVisible(img.parentNode) && !img.complete) {
            img.src = url
        }
        if (!img.complete) img.style.display = "none"
        img.onload = () => {
            img.dataset['has-load'] = 'true'
            img.style.display = "inline-block"
            img.style.height = 'auto'
        }

        img.onerror = () => {
            img.dataset['has-load'] = 'false'
            img.style.display = "none"
            img.removeAttribute('src')
            img.style.height = '0px'
        }
    }
}

export const appLoadAction = () => {
    let imgArr = [].slice.call(document.querySelectorAll('.lazy-load-pic'));
    lazyLoadImg(imgArr);
    document.addEventListener('scroll', throttle(() => {
        lazyLoadImg(imgArr);
    }, 600))
}

//下拉刷新
export const pullFresh = (freshCb) => {
    const scroll = document.querySelector('#scroll') || document.querySelector('#app')
    if (scroll) {
        const touchHandler = {
            outerScroller: scroll,
            touchStart: {
                x: 0,
                y: 0
            },
            scroll: scroll,
            isSingle: true // 单手touch
        }
        touchHandler.outerScroller.addEventListener(
            'touchstart',
            function (event) {
                var touch = event.targetTouches[0];
                touchHandler.isSingle = event.touches.length < 2
                touchHandler.touchStart.y = touch.pageY;
                touchHandler.touchStart.x = touch.pageX;
            },
            { passive: true }
        );

        touchHandler.outerScroller.addEventListener(
            'touchmove',
            function (e) {
                var touch = e.targetTouches[0];
                if (isTop() && (touch.pageY - touchHandler.touchStart.y) > 10 && Math.abs(touch.pageX - touchHandler.touchStart.x) < 39) {
                    touchHandler.outerScroller.style.transform = "translateY(50px)";
                    touchHandler.outerScroller.style.transition = "all ease .9s"
                }
            },
            { passive: true }
        );

        touchHandler.outerScroller.addEventListener(
            'touchend',
            function (event) {
                touchHandler.outerScroller.style.transform = "translateY(0)";
                touchHandler.outerScroller.style.transition = "all ease 0.9s"

                const touch = event.changedTouches[0];
                if (touchHandler.isSingle) {
                    const disX = touch.pageX - touchHandler.touchStart.x,
                        disY = touch.pageY - touchHandler.touchStart.y

                    if (touchHandler.isSingle && isTop() && disY > 90 && Math.abs(disX) < 199 && (Math.abs(disX) < Math.abs(disY) + 36) && freshCb) {
                            freshCb()
                    };

                    touchHandler.touchStart = {
                        x: 0,
                        y: 0
                    };
                }
                
            }, { passive: true }
        );
    }
}

//时间处理
export const formatTime = (ts) => {
    if (ts === 0) return ''
    const ft = (t) => t > 9 ? t : '0' + t
    return Math.floor(ts / 3600) + ':' + ft(Math.floor(Math.floor(ts % 3600) / 60)) + ":" + ft(ts % 60)
}

// 上拉加载
export const pullRequest = () => {
    let tm;
    window.onscroll = function () {
        if (tm) clearTimeout(tm)
        tm = setTimeout(async () => {
            const scrollH = document.documentElement.scrollHeight;
            const scrollT = document.documentElement.scrollTop || document.body.scrollTop;
            const screenH = window.screen.height;
            const d = scrollH - scrollT - screenH

            if (d < 6) {
                if (isLast.value) return
                if (!navigator?.onLine) {
                    isWithoutNetX.value = true
                    isLoading.value = false
                    return
                }
                currentPage.value++
                await getDataList()
                appLoadAction()
            }
        }, 100)
    };
}

export const transPic = (picAddress, c) => {
    const w = window.screen.width + c
    const adr = `${picAddress}?x-oss-process=image/resize,w_${w}/format,webp`
    return adr
}