折腾:
期间,还是无法使用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的混合事件是啥
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
然后去试试:
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; } |
效果: