Javascript 检测页面底部以在react中获取更多数据
我尝试了几个资源中的代码来检测用户是否已经到达页面底部,然后获取更多数据。它的工作,但功能总是获取数据每当我滚动,而不是每当用户到达底部。这是我的密码:Javascript 检测页面底部以在react中获取更多数据,javascript,css,reactjs,infinite-scroll,Javascript,Css,Reactjs,Infinite Scroll,我尝试了几个资源中的代码来检测用户是否已经到达页面底部,然后获取更多数据。它的工作,但功能总是获取数据每当我滚动,而不是每当用户到达底部。这是我的密码: import React, { Component } from 'react'; class DataView extends Component { constructor(props) { super(props); this.state = { displayedData: [], ini
import React, { Component } from 'react';
class DataView extends Component {
constructor(props) {
super(props);
this.state = {
displayedData: [],
initialData: [],
loadingState: false,
};
this.fetchMoreData = this.fetchMoreData.bind(this);
this.handleScroll = this.handleScroll.bind(this);
}
componentDidMount() {
window.addEventListener('scroll', this.handleScroll, true);
}
componentWillReceiveProps(props) {
const initialData = props.initialData;
this.setState({
initialData,
displayedData: initialData.slice(0, 3),
});
}
componentWillUnmount() {
window.removeEventListener('scroll', this.handleScroll, true);
}
fetchMoreData() {
console.log('fetch');
this.setState({ loadingState: true });
if (this.state.displayedData.length >= this.state.initialData.length) {
this.setState({
loadingState: false,
});
return;
}
const size = 3;
const initialData = this.state.initialData;
const copiedinitialData = [...initialData];
const prevDisplayedData = this.state.displayedData;
const copiedPrevDisplayedData = [...prevDisplayedData];
const copiedPrevDisplayedDataLength = copiedPrevDisplayedData.length;
const nextItem = copiedinitialData.slice(copiedPrevDisplayedDataLength, copiedPrevDisplayedDataLength + size);
copiedPrevDisplayedData.push(...nextItem);
setTimeout(() => {
this.setState({
displayedData: copiedPrevDisplayedData,
});
}, 2000);
// use set timeout because fetching data still use mock data (not hitting API)
}
handleScroll() {
// FIRST TRIAL
// const scrollTop = document.getElementById('isScrolling').scrollTop;
// const clientHeight = document.getElementById('isScrolling').clientHeight;
// const scrollHeight = document.getElementById('react-element').scrollHeight; // the id is written in another component as the outer element/wrapper
// console.log('============= ### =============');
// console.log('scrollTop: ', scrollTop);
// console.log('clientHeight: ', clientHeight);
// console.log('scrollHeight: ', scrollHeight);
// console.log('scrollHeight2: ', scrollHeight2);
// console.log('============= ### =============');
// if (scrollTop + clientHeight >= scrollHeight) {
// this.fetchMoreData();
// }
// above working but always fetch when scrolled, not when user reach bottom
// SECOND TRIAL
// const lastDiv = document.querySelector('#isScrolling > div:last-child');
// const lastDivOffset = lastDiv.offsetTop + lastDiv.clientHeight;
// const pageOffset = window.pageYOffset + window.innerHeight;
// console.log('============= ### =============');
// console.log('lastDivOffset: ', lastDivOffset);
// console.log('pageOffset: ', pageOffset);
// console.log('clientHeight: ', document.getElementById('isScrolling').clientHeight);
// console.log('scrollHeight: ', document.getElementById('isScrolling').scrollHeight);
// console.log('lastDivOffsetTop: ', lastDiv.offsetTop);
// console.log((pageOffset / lastDivOffset) * 100);
// console.log('============= ### =============');
// const ratio = (pageOffset / lastDivOffset) * 100;
// let scenario = ratio < 60;
// let scenario = pageOffset > lastDivOffset - 10;
// if (scenario) {
// this.fetchMoreData();
// }
// both of the scenario behave like the first trial
console.log('============= ### =============');
console.log('win screen: ', window.screen);
console.log('win screenTop: ', window.screenTop);
console.log('win screenLeft: ', window.screenLeft);
console.log('win screenY: ', window.screenY);
console.log('win scrollY: ', window.scrollY);
console.log('win innerHeight: ', window.innerHeight); // always 580
console.log('win pageYOffset: ', window.pageYOffset);
console.log('docEl clientHeight: ', document.documentElement.clientHeight);
console.log('docEl clientLeft: ', document.documentElement.clientLeft);
console.log('docEl clientTop: ', document.documentElement.clientTop);
console.log('docEl offsetHeight: ', document.documentElement.offsetHeight);
console.log('docEl scrollHeight: ', document.documentElement.scrollHeight);
console.log('docEl scrollLeft: ', document.documentElement.scrollLeft);
console.log('docEl screenTop: ', document.documentElement.scrollTop);
console.log('docBody clientHeight: ', document.body.clientHeight);
console.log('docBody clientLeft: ', document.body.clientLeft);
console.log('docBody clientTop: ', document.body.clientTop);
console.log('docBody offsetHeight: ', document.body.offsetHeight);
console.log('docBody scrollHeight: ', document.body.scrollHeight);
console.log('docBody scrollLeft: ', document.body.scrollLeft);
console.log('docBody screenTop: ', document.body.scrollTop);
console.log('docId scrollHeight: ', document.getElementById('isScrolling').scrollHeight); // ==> A
console.log('docId screenLeft: ', document.getElementById('isScrolling').scrollLeft);
console.log('docId scrollTop: ', document.getElementById('isScrolling').scrollTop);
console.log('docId clientHeight: ', document.getElementById('isScrolling').clientHeight); // ==> B
console.log('docId offsetHeight: ', document.getElementById('isScrolling').offsetHeight); // ==> C
// the A value is always 20px greater than B and C. B and C is always same value. The others console.log result is zero
console.log('============= ### =============');
if ((window.scrollY + window.innerHeight) >= document.body.scrollHeight) {
// this if statement also behave like the first trial
this.fetchMoreData();
}
}
render() {
const displayedData = this.state.displayedData.map((item, index) => {
const itemIndex = index;
const dataName = item.dataName;
return <div key={itemIndex} style={{ marginBottom: 20 }}>
{dataName}
</div>;
});
return (
<div>
<div className="class">
<div className="name">
{/* {another code} */}
</div>
<div className="classes">
{/* {another code} */}
</div>
<div id="isScrolling">
{displayedData}
{this.state.loadingState
? <div> Loading ....</div>
: <div> No more data available</div>
}
</div>
</div>
</div>
);
}
}
export default DataView;
import React,{Component}来自'React';
类DataView扩展组件{
建造师(道具){
超级(道具);
此.state={
显示数据:[],
初始数据:[],
加载状态:false,
};
this.fetchMoreData=this.fetchMoreData.bind(this);
this.handleScroll=this.handleScroll.bind(this);
}
componentDidMount(){
window.addEventListener('scroll',this.handleScroll,true);
}
组件将接收道具(道具){
const initialData=props.initialData;
这是我的国家({
初始数据,
displayedData:initialData.slice(0,3),
});
}
组件将卸载(){
window.removeEventListener('scroll',this.handleScroll,true);
}
fetchMoreData(){
log('fetch');
this.setState({loadingState:true});
if(this.state.displayedData.length>=this.state.initialData.length){
这是我的国家({
加载状态:false,
});
返回;
}
常数大小=3;
const initialData=this.state.initialData;
常量copiedinitialData=[…initialData];
const prevDisplayedData=this.state.displayedData;
常量copiedPrevDisplayedData=[…prevDisplayedData];
const copiedPrevDisplayedDataLength=copiedPrevDisplayedData.length;
const nextItem=copiedinitialData.slice(copiedPrevDisplayedDataLength,copiedPrevDisplayedDataLength+大小);
copiedPrevDisplayedData.push(…下一个);
设置超时(()=>{
这是我的国家({
displayedData:copiedPrevDisplayedData,
});
}, 2000);
//使用设置超时,因为提取数据仍然使用模拟数据(不命中API)
}
handleScroll(){
//初审
//constScrollTop=document.getElementById('isScrolling').scrollTop;
//const clientHeight=document.getElementById('isScrolling').clientHeight;
//const scrollHeight=document.getElementById('react-element').scrollHeight;//该id作为外部元素/包装写入另一个组件中
//console.log('=============================================================================================');
//log('scrollTop:',scrollTop);
//log('clientHeight:',clientHeight);
//log('scrollHeight:',scrollHeight);
//log('scrollHeight2:',scrollHeight2);
//console.log('=============================================================================================');
//如果(scrollTop+clientHeight>=滚动高度){
//this.fetchMoreData();
// }
//但总是在滚动时提取,而不是在用户到达底部时提取
//二审
//const lastDiv=document.querySelector('isScrolling>div:last child');
//const lastDivOffset=lastDiv.offsetTop+lastDiv.clientHeight;
//const pageOffset=window.pageYOffset+window.innerHeight;
//console.log('=============================================================================================');
//log('lastDivOffset:',lastDivOffset);
//log('pageOffset:',pageOffset);
//console.log('clientHeight:',document.getElementById('isScrolling').clientHeight);
//console.log('scrollHeight:',document.getElementById('isScrolling').scrollHeight);
//log('lastDivOffsetTop:',lastDiv.offsetTop);
//控制台日志((pageOffset/lastDivOffset)*100);
//console.log('=============================================================================================');
//常数比=(pageOffset/lastDivOffset)*100;
//假设情景=比率<60;
//让scenario=pageOffset>lastDivOffset-10;
//如果(场景){
//this.fetchMoreData();
// }
//这两种情况的表现都类似于第一次审判
console.log('=============================================================================================');
console.log('win screen:',window.screen);
console.log('win screenTop:',window.screenTop);
console.log('win screenlight:',window.screenlight);
log('win screenY:',window.screenY);
log('win scrollY:',window.scrollY);
console.log('win-innerHeight:',window.innerHeight);//始终580
log('win pageYOffset:',window.pageYOffset);
log('docEl clientHeight:',document.documentElement.clientHeight);
log('docEl clientLeft:',document.documentElement.clientLeft);
log('docEl clientTop:',document.documentElement.clientTop);
log('docEl offsetHeight:',document.documentElement.offsetHeight);
console.log('docEl scrollHeight:',document.documentElement.scrollHeight);
log('docEl scrollLeft:',document.documentElement.scrollLeft);
console.log('docEl screenTop:',document.documentElement.scrollTop);
log('docBody clientHeight:',document.body.clientHeight);
log('docBody clientLeft:',document.body.clientLeft);
log('docBody clientTop:',document.body.clientTop);
log('docBody offsetHeight:',document.body.offsetHeight);
console.log('docBody scrollHeight:',document.body.scrollHeight);
log('docBody scrollLeft:',document.body.scrollLeft');
console.log('docBody screenTop:',document.body.scrollTop);
console.log('docId scrollHeight:',document.getElementById('isScrolling').scrollHeight);//=>A
console.log('docId screensleft:',document.getElementById('isScrolling').scrollLeft);
console.log('docId scrollTop:',document.getElementById('isScrolling').scrollTop);
console.log('docId clientHeight:',document.getElementById('isScrolling').clientHeight);//=>B
console.log('docId offsetHeight:',document.getElementById('isScrolling').offsetHeight);//=>C
//A值始终比B和C大20px。B和C值始终相同。其他console.log结果为零
console.log('=============================================================================================');
if((window.scrollY+window.innerHeight)>=document.body.scrollHeight){
//这个
window.addEventListener('scroll', function() {
if ((window.innerHeight + window.scrollY) >= document.body.offsetHeight) {
console.log("you're at the bottom of the page");
// Show loading spinner and make fetch request to api
}
});
constructor(props) {
super(props);
this.state = {
height: window.innerHeight,
message: 'not at bottom'
};
this.handleScroll = this.handleScroll.bind(this);
}
handleScroll() {
const windowHeight = "innerHeight" in window ? window.innerHeight : document.documentElement.offsetHeight;
const body = document.body;
const html = document.documentElement;
const docHeight = Math.max(body.scrollHeight, body.offsetHeight, html.clientHeight, html.scrollHeight, html.offsetHeight);
const windowBottom = windowHeight + window.pageYOffset;
if (windowBottom >= docHeight) {
this.setState({
message: 'bottom reached'
});
} else {
this.setState({
message: 'not at bottom'
});
}
}
componentDidMount() {
window.addEventListener("scroll", this.handleScroll);
}
componentWillUnmount() {
window.removeEventListener("scroll", this.handleScroll);
}
useEffect(() => {
const onScroll = function () {
if (window.innerHeight + window.scrollY >= document.body.offsetHeight) {
console.log("you're at the bottom of the page")
}
}
window.addEventListener('scroll', onScroll)
return () => window.removeEventListener('scroll', onScroll)
}, [])
useEffect(() => {
const scrolling_function = () => {
if((window.innerHeight + window.scrollY) >= document.body.offsetHeight-10){
console.log("fetching more.........")
window.removeEventListener('scroll',scrolling_function)
}
}
window.addEventListener('scroll', scrolling_function);
}, [target_data])