<template>
    <div
        ref="boxRef"
        class="box"
        v-loading="loading"
    >
        <div ref="contentRef">
            <h3>———下拉加载更多数据———</h3>
            <h2
                v-for="(item, index) in list"
                :key="index"
            >
                {{ item }}
            </h2>
            <h1>请使用移动端调试模式打开</h1>
            <h2>这里是模拟数据1</h2>
            <h2>这里是模拟数据1</h2>
            <h2>这里是模拟数据1</h2>
            <h2>这里是模拟数据1</h2>
            <h2>这里是模拟数据1</h2>
            <h2>首屏数据到此</h2>
            <h2>模拟数据不够一页下拉加载</h2>
        </div>
    </div>
</template>

<script setup lang="jsx">
import { ref, onMounted, onBeforeUnmount, nextTick } from 'vue';
import { debounce } from '@pureadmin/utils';

const boxRef = ref(null);
const contentRef = ref(null);
const list = ref([]);
const loading = ref(false);
let startY = 0;
const beforeHeight = ref(null);

const getData = () => {
    console.log(contentRef.value.clientHeight, '内部内容的整体高度');
    console.log('加载数据');
    beforeHeight.value = contentRef.value.clientHeight;
    setTimeout(() => {
        loading.value = false;
        let tempList = [];
        let currentLength = list.value.length;
        for (let i = 20; i > 0; i--) {
            tempList.push(`模拟数据${i + currentLength}`);
        }
        list.value = tempList.concat(list.value);
        // 下拉加载数据，滚动条滚动到加载数据前位置
        nextTick(() => (boxRef.value.scrollTop = contentRef.value.clientHeight - beforeHeight.value));
    }, 2000);
};
const handleTouchstart = (e) => {
    startY = e.touches[0].clientY;
};
const handleTouchmove = (e) => {
    console.log('监听鼠标移动事件', e);
    if (!shouldHandleTouch()) {
        return;
    }
    const currentY = e.touches[0].clientY;
    if (currentY - startY > 100) {
        e.preventDefault && e.preventDefault();
        loading.value = true;
        // 这里调用是因为debounce的原因，debounc会延迟，导致touchend事件先执行，所以这里需要手动触发一次
        handleTouchend();
    }
};
const debounceHandleTouchmove = debounce(handleTouchmove, 500);
const handleTouchend = () => {
    if (loading.value) {
        getData();
    }
};
const shouldHandleTouch = () => {
    console.log(boxRef.value.scrollTop, '整个容器当前滚动条位置');
    if (boxRef.value.scrollTop > 0 || loading.value) {
        return false;
    }
    return true;
};

const addTouchEventListeners = () => {
    boxRef.value.addEventListener('touchstart', handleTouchstart);
    boxRef.value.addEventListener('touchmove', debounceHandleTouchmove);
    boxRef.value.addEventListener('touchend', handleTouchend);
};
const removeTouchEventListeners = () => {
    boxRef.value.removeEventListener('touchstart', handleTouchstart);
    boxRef.value.removeEventListener('touchmove', debounceHandleTouchmove);
    boxRef.value.removeEventListener('touchend', handleTouchend);
};

onMounted(() => {
    addTouchEventListeners();
});
onBeforeUnmount(() => {
    removeTouchEventListeners();
});
</script>

<style lang="scss" scoped>
.box {
    display: flex;
    flex-direction: column;
    align-items: center;
    background: #fff;
    height: calc(100vh - 81px);
    overflow-x: hidden;
    overflow-y: auto;

    h2 {
        padding: 10px 0;
    }
}
</style>
