最新消息:20210816 当前crifan.com域名已被污染,为防止失联,请关注(页面右下角的)公众号

【已解决】ReactJS中如何判断页面滚动到底部以实现下拉加载更多页面数据

ReactJS crifan 4536浏览 0评论

折腾:

【已解决】ReactJS中如何实现上拉加载更多数据

期间,还是无法使用react-infinite-scroller库,去实现上拉加载更多页数据。

通过调试,感觉是滚动距离的判断有问题

所以算了,自己去想办法实现:

如何判断页面滚动到了底部

从而触发加载更多页的数据

reactjs check scroll down to bottom

reactjs – How to scroll to bottom in react? – Stack Overflow

Detect When User Scrolls To Bottom of Page with ReactJS | SodhanaLibrary

其去监听scroll事件

此处需要去搞清楚ReactJS中scroll的混合事件是啥

SyntheticEvent – React

onScroll

Element.scrollIntoView() – Web APIs | MDN

-》

Element.scrollHeight – Web APIs | MDN

The following equivalence returns true if an element is at the end of its scroll, false if it isn’t.
element.scrollHeight – element.scrollTop === element.clientHeight

官网都说了,上面的公式就是用于计算是否滚动到底部的判断标准,而之前的:

InfiniteScroll中,也是这样写的:

      // offset = el.scrollHeight – el.parentNode.scrollTop – el.parentNode.clientHeight;
      // offset = el.offsetHeight – el.parentNode.scrollTop – el.parentNode.clientHeight;
      // offset = el.parentNode.scrollHeight – el.parentNode.scrollTop – el.parentNode.clientHeight;
      offset = el.scrollHeight – el.scrollTop – el.clientHeight;

都试了,都没用啊。

Vjeux » Scroll Position with React

The simplest way to make a pull-to-refresh and infinite tableview with ReactJS

【已解决】ReactJS中onScroll不触发不起效果

然后去试试:

  onListScroll(e){
    console.log(`onListScroll`);
    // console.log(e);
    console.log(e.srcElement);
    console.log(e.target);
    let srcElement = e.srcElement;
    console.log(`srcElement.scrollHeight=${srcElement.scrollHeight}, srcElement.scrollTop=${srcElement.scrollTop}, srcElement.clientHeight=${srcElement.clientHeight}`);
    let targetElement = e.target;
    let remainHeight = targetElement.scrollHeight – targetElement.scrollTop;
    let isReachBottom =  (remainHeight <= targetElement.clientHeight);
    console.log(`targetElement.scrollHeight=${targetElement.scrollHeight}, targetElement.scrollTop=${targetElement.scrollTop}, targetElement.clientHeight=${targetElement.clientHeight} -> remainHeight=${remainHeight}, isReachBottom=${isReachBottom}`);
    if (isReachBottom){
      this.searchCowshedListByBlur();
    }
  }

果然是可以获得滚动高度的,对应着scrollTop

然后滑动到底部时,可以满足条件:

此处对应着:

targetElement.scrollHeight – targetElement.scrollTop == targetElement.clientHeight

1537 – 870 == 667

然后就是滚动到底了。

【总结】

然后就是去加载更多页面数据了

并且加上一个loading的标识:

代码:

import { h, Component } from ‘preact’;
import { Link } from ‘preact-router’;
import autoBind from ‘react-autobind’;
import { connect } from ‘preact-redux’;
import { bindActions } from ‘../../../store/util’;
import reducer from ‘../../../store/reducers’;
import * as actions from ‘../../../store/actions’;
import style from ‘./style.less’;
import Search from ‘../../../components/search’;
import { ROUTE_PREFIX } from “../../../common/define”;
import config from ‘../../../config’;
@connect(reducer, bindActions(actions))
export default class CowshedManagement extends Component {
  state = {
    curPageNum : 1,
    isLoading : false,
    // isLoading : true,
    cowshedList: [],
    cowshedTypeList : [
      {
        // “ids”    : “”,
        “val” : “”,
        “names”  : “”
      }
    ],
    cowshedTypeDict : {
      //”val” -> “names”
    }
  };
  constructor(props) {
    super(props);
    autoBind(this);
    this.onListScroll = this.onListScroll.bind(this);
    this.onSearchClick = this.onSearchClick.bind(this);
    this.searchKeyword = “”;
    this.fetchCowshedTypeDict();
    this.searchCowshedListByList();
  }
  componentDidMount() {
    console.log(`CowshedManagement componentDidMount`);
    // console.log(this.scrollItem);
    // this.scrollItem.addEventListener(‘scroll’, this.onListScroll);
    // this.scrollItem.addEventListener(‘scroll’, this.onListScroll, true);
    window.addEventListener(‘scroll’, this.onListScroll, true);
  }
  componentWillUnmount() {
    console.log(`CowshedManagement componentWillUnmount`);
    // console.log(this.scrollItem);
    // this.scrollItem.removeEventListener(‘scroll’, this.onListScroll);
    // this.scrollItem.removeEventListener(‘scroll’, this.onListScroll, true);
    window.removeEventListener(‘scroll’, this.onListScroll, true);
  }
  fetchCowshedTypeDict() {
    console.log(“fetchCowshedTypeDict”);
    const url = `/dict/dict/cowshedtype`;
    this.props.fetch(url, {}, ( data ) => {
      console.log(data);
      let typeDict = {};
      for (let eachType of data){
        typeDict[eachType.val] = eachType.names;
      }
      console.log(typeDict);
      this.setState({
        cowshedTypeList: data,
        cowshedTypeDict : typeDict
      });
    });
  }
  searchCowshedListByList() {
  // searchCowshedListByList(start = 1) {
    // //const url = `/cowshed/cowshed/search/list?start=${start}&limit=${config.numPerPage}`;
    // const url = `/cowshed/cowshed/search/list?start=${start}&limit=${9}`;
    // this.props.fetch(url, {}, ( data ) => {
    //   console.log(data);
    //   // console.log(data.data);
    //   // console.log(`data=${data},total_num=${total_num}`);
    //   const { cowshedList } = this.state;
    //   this.setState({
    //     cowshedList: start === 1 ? data : cowshedList.concat(data)
    //     // cowshedList: start === 1 ? data.data : cowshedList.concat(data.data)
    //   });
    // });
    this.searchCowshedListByBlur(“”);
  }
  // searchCowshedListByBlur(keyword=””, start = 1) {
  searchCowshedListByBlur(keyword=””) {
    this.setState({isLoading : true});
    console.log(`keyword=${keyword},this.state.curPageNum=${this.state.curPageNum}`);
    // const url = `/cowshed/cowshed/search/blur?keyword=${keyword}&start=${start}&limit=${config.numPerPage}`;
    const url = `/cowshed/cowshed/search/blur?keyword=${keyword}&start=${this.state.curPageNum}&limit=${config.numPerPage}`;
    //for debug
    // const url = `/cowshed/cowshed/search/blur?keyword=${keyword}&start=${this.state.curPageNum}&limit=${10}`;
    this.props.fetch(url, {}, ( data ) => {
      this.setState({isLoading : false});
      console.log(data);
      // console.log(data.data);
      // console.log(`data=${data},total_num=${total_num}`);
      if (data && (data.length > 0)){
        const prevCowshedList = this.state.cowshedList;
        const prevPageNum = this.state.curPageNum;
        this.setState({
          cowshedList: prevPageNum === 1 ? data : prevCowshedList.concat(data),
          curPageNum : prevPageNum + 1
        });
      }
      console.log(`after searchCowshedListByBlur: this.state.curPageNum=${this.state.curPageNum}`);
    });
  }
  resetPageNum(){
    let prePageNum = this.state.curPageNum;
    this.setState({curPageNum : 1});
    console.log(`resetPageNum: ${prePageNum} -> ${this.state.curPageNum}`);
  }
  onInputChange(currentValue){
    this.searchKeyword = currentValue;
    this.resetPageNum();
    this.searchCowshedListByBlur(this.searchKeyword);
  }
  onListScroll(e){
    console.log(`onListScroll`);
    // console.log(e);
    console.log(e.srcElement);
    console.log(e.target);
    let srcElement = e.srcElement;
    console.log(`srcElement.scrollHeight=${srcElement.scrollHeight}, srcElement.scrollTop=${srcElement.scrollTop}, srcElement.clientHeight=${srcElement.clientHeight}`);
    let targetElement = e.target;
    let remainHeight = targetElement.scrollHeight – targetElement.scrollTop;
    let isReachBottom =  (remainHeight <= targetElement.clientHeight);
    console.log(`targetElement.scrollHeight=${targetElement.scrollHeight}, targetElement.scrollTop=${targetElement.scrollTop}, targetElement.clientHeight=${targetElement.clientHeight} -> remainHeight=${remainHeight}, isReachBottom=${isReachBottom}`);
    if (isReachBottom){
      this.searchCowshedListByBlur();
    }
  }
  onSearchClick(e){
    console.log(“onSearchClick”);
    console.log(e);
    this.resetPageNum();
  }
  showLoading(){
    if (this.state.isLoading) {
      return (
        <div class={style.loading}>正在加载…</div>
      );
    }
    return null;
  }
  render() {
    const { cowshedList, cowshedTypeDict } = this.state;
        //     ref={(scrollItem) => {this.scrollItem = scrollItem;}}
        // onScroll={this.onListScroll}
        // <ul
        //   class={style.nn_a_list}
        // >
    return (
      <div
        class={style.the_herd_all}
        >
        <Search
          placeholder=”请输入牛舍号搜索”
          onClick={this.onSearchClick}
          onInputChange={this.onInputChange}
        />
        <div
          class={style.nn_a_list}
        >
          {
            cowshedList.map(item => {
              return (
                <CowshedListItem data={item} cowshedTypeDict={cowshedTypeDict} />
              );
            })
          }
          {this.showLoading()}
        </div>
      </div>
    );
  }
}
function CowshedListItem({ data, cowshedTypeDict}) {
  const {
    name,
    cowshedtype,
    id,
    capacity,
    current_cow_num
  } = data;
  return (
    <Link href={`${ROUTE_PREFIX.COWSHED_EDIT}/${id}`}>
      <div class={style.item}>
        <div>
          <p>牛舍:<span>{name}</span></p>
          <p>容量:{capacity}</p>
        </div>
        <div>
          <div/>
          <div>在舍牛头数:{current_cow_num}</div>
        </div>
        <label>{cowshedTypeDict[cowshedtype]}</label>
      </div>
    </Link>
  );
}

cowshed-management/style.less

.the_herd_all {
  // display: none;
  // overflow: auto;
  // overflow: scroll;
  // overflow-y: scroll;
}
.nn_a_list {
  // height: 100%;
  // overflow-y: auto;
}
.loading {
    border-top: 1px solid #cccac9;
  text-align: center;
}

效果:

转载请注明:在路上 » 【已解决】ReactJS中如何判断页面滚动到底部以实现下拉加载更多页面数据

发表我的评论
取消评论

表情

Hi,您需要填写昵称和邮箱!

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址
89 queries in 0.164 seconds, using 22.19MB memory