react实现Dom元素滚动到底部分页加载数据,渲染列表

主要的代码如下:

import React, { Component } from 'react';
import axios from 'axios';
import './App.css';
// import dayjs from "dayjs";
// import duration from 'dayjs/plugin/duration';
// dayjs.extend(duration);

export default class App extends Component {
    constructor(props) {
        super(props)
        // 初始化参数
        this.state = {
            list:[],
            totalFriend:0
        }
        // 设置滚动前的滚动距离,默认为0
        this.beforeScrollTop = 0;
    }
    componentDidMount = () => {
        // 页面加载完成的是请求列表
        this.getFriendList();
      }
    //   请求列表的函数(实际接口需要传参,此处忽略)
      getFriendList = () => {
          axios.get("friendList.json").then((res) => {
              let listArr = this.state.list;
            // 分页加载的逻辑
              listArr.push(...res.data.data);
            //  请求回来的数据--赋值
              this.setState({
                  list:listArr,
                  totalFriend:res.data.totalFriend
              })
          })
      }

      scrollHandle = ()=>{
        const wrapDom = document.getElementsByClassName("friend-view")[0],//获取最外层的dom
            contentDom = document.getElementsByClassName("content")[0],//获取内容区的dom
            scrollTop = wrapDom.scrollTop,//获取最外层的scrollTop
            scrollHeight = contentDom.scrollHeight,//获取内容区的scrollHeight
            clientHeight = wrapDom.clientHeight,//获取最外层的clientHeight
            afterScrollTop = wrapDom.scrollTop,//设置滚动后的afterScrollTop
            gayValue = afterScrollTop - this.beforeScrollTop,//设置滚动前后的scrollTop的差值
            {list, totalFriend} = this.state, //解构数据
            BOTTOM_LENGTH = 1 //设置距离底部xx像素(不带单位)开始加载


            if(gayValue >= 0 ){
                console.log("往下滚动");
                if (scrollTop + clientHeight + BOTTOM_LENGTH >= scrollHeight) {
                    console.log("滚动到底部了");
                    // 如果数组的长度 >= totalFriend,说明已经加载完所有的数据了,即使再滚动到底部也不需要加载了
                    if (list.length >= totalFriend) {
                        return;
                    }
                    // 如果数组的长度 >= totalFriend  继续加载数据
                    this.getFriendList();
                }
            } else {
                console.log("往上滚动,看情况做逻辑");
            }

            // 把afterScrollTop赋值给this.beforeScrollTop
            this.beforeScrollTop = afterScrollTop;
      }
    render() {
        const {list, totalFriend} = this.state;
        console.log("render", list, totalFriend);
        return (
            // 外层的盒子
            <div className='friend-view' onScroll={this.scrollHandle}>
                {/* 内容去 */}
                <div className="content">
                    {list && list.map((item, index) => {
                        return (
                        <div className='item' key={index}>{item.friendName}</div>
                        )
                    })}
                </div>
                {/* 底部的提示语 */}
                {list.length !== 0 && list.length >= totalFriend && <div className='footer-tip'>我也是有底线的</div>}
            </div>
        )
    }
}

本地模拟的json数据如下:

{
    "respCode":"1000",
    "respMsg":"成功",
    "totalFriend":15,
    "data":[
        {"id":"001","friendName":"1"},
        {"id":"002","friendName":"2"},
        {"id":"003","friendName":"3"},
        {"id":"004","friendName":"4"},
        {"id":"005","friendName":"5"}
    ]
}

css样式如下:

.friend-view{
    width: 300px;
    height: 400px;
    border: 1px  solid red;
    overflow: auto;
}
.friend-view::-webkit-scrollbar{
    display: none;
    width: 0 !important;
    height: 0 !important;

}
.content{
    width: 100%;
}
.item{
    width: 100%;
    height: 80px;
    margin-bottom: 10px;
    background-color: skyblue;
    /* color: #fff; */
    line-height: 80px;
    text-align: center;
    font-size: 24px;
}
.footer-tip{
    margin: 0 auto;
    background-color: #ccc;
    line-height: 40px;
    color: red;
    width: 100%;
    height: 40px;
    text-align: center;
}

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值