我有一个不同部分的网站.我正在使用segment.io来跟踪页面上的不同操作.如何检测用户是否已滚动到div的底部?我尝试过以下但是当我滚动页面时它似乎被触发而不是当我到达div的底部时.
componentDidMount() {
document.addEventListener('scroll', this.trackScrolling);
}
trackScrolling = () => {
const wrappedElement = document.getElementById('header');
if (wrappedElement.scrollHeight - wrappedElement.scrollTop === wrappedElement.clientHeight) {
console.log('header bottom reached');
document.removeEventListener('scroll', this.trackScrolling);
}
};
Run Code Online (Sandbox Code Playgroud)
Bre*_*ill 49
更简单的方法是使用scrollHeight,scrollTop和clientHeight.
您只需从总可滚动高度中减去滚动高度.如果这等于可见区域,那么你就到了底部!
element.scrollHeight - element.scrollTop === element.clientHeight
Run Code Online (Sandbox Code Playgroud)
在react中,只需将onScroll侦听器添加到可滚动元素,并event.target在回调中使用.
class Scrollable extends Component {
handleScroll = (e) => {
const bottom = e.target.scrollHeight - e.target.scrollTop === e.target.clientHeight;
if (bottom) { ... }
}
render() {
return (
<ScrollableElement onScroll={this.handleScroll}>
<OverflowingContent />
</ScrollableElement>
);
}
}
Run Code Online (Sandbox Code Playgroud)
我发现这更直观,因为它处理可滚动元素本身,而不是window,它遵循正常的React方式(不使用id,忽略DOM节点).
您还可以操纵方程式以触发更高的页面(例如,延迟加载内容/无限滚动).
eww*_*ink 39
你可以el.getBoundingClientRect().bottom用来检查底部是否被查看过
isBottom(el) {
return el.getBoundingClientRect().bottom <= window.innerHeight;
}
componentDidMount() {
document.addEventListener('scroll', this.trackScrolling);
}
componentWillUnmount() {
document.removeEventListener('scroll', this.trackScrolling);
}
trackScrolling = () => {
const wrappedElement = document.getElementById('header');
if (this.isBottom(wrappedElement)) {
console.log('header bottom reached');
document.removeEventListener('scroll', this.trackScrolling);
}
};
Run Code Online (Sandbox Code Playgroud)
All*_*ney 14
这是使用 React Hooks 和 ES6 的解决方案:
import React, { useRef, useEffect } from 'react';
const MyListComponent = () => {
const listInnerRef = useRef();
const onScroll = () => {
if (listInnerRef.current) {
const { scrollTop, scrollHeight, clientHeight } = listInnerRef.current;
if (scrollTop + clientHeight === scrollHeight) {
// TO SOMETHING HERE
console.log('Reached bottom')
}
}
};
return (
<div className="list">
<div className="list-inner" onScroll={() => onScroll()} ref={listInnerRef}>
{/* List items */}
</div>
</div>
);
};
export default List;
Run Code Online (Sandbox Code Playgroud)
小智 6
我们还可以使用ref检测div的滚动结束。
import React, { Component } from 'react';
import {withRouter} from 'react-router-dom';
import styles from 'style.scss';
class Gallery extends Component{
paneDidMount = (node) => {
if(node) {
node.addEventListener("scroll", this.handleScroll.bind(this));
}
}
handleScroll = (event) => {
var node = event.target;
const bottom = node.scrollHeight - node.scrollTop === node.clientHeight;
if (bottom) {
console.log("BOTTOM REACHED:",bottom);
}
}
render() {
var that = this;
return(<div className={styles.gallery}>
<div ref={that.paneDidMount} className={styles.galleryContainer}>
...
</div>
</div>);
}
}
export default withRouter(Gallery);
Run Code Online (Sandbox Code Playgroud)
小智 6
扩展 chandresh 的答案以使用 react hooks 和 ref 我会这样做;
import React, {useState, useEffect} from 'react';
export default function Scrollable() {
const [referenceNode, setReferenceNode] = useState();
const [listItems] = useState(Array.from(Array(30).keys(), (n) => n + 1));
useEffect(() => {
return () => referenceNode.removeEventListener('scroll', handleScroll);
}, []);
function handleScroll(event) {
var node = event.target;
const bottom = node.scrollHeight - node.scrollTop === node.clientHeight;
if (bottom) {
console.log('BOTTOM REACHED:', bottom);
}
}
const paneDidMount = (node) => {
if (node) {
node.addEventListener('scroll', handleScroll);
setReferenceNode(node);
}
};
return (
<div
ref={paneDidMount}
style={{overflowY: 'scroll', maxHeight: '400px'}}
>
<ul>
{listItems.map((listItem) => <li>List Item {listItem}</li>)}
</ul>
</div>
);
}
Run Code Online (Sandbox Code Playgroud)
在你的 React.Component 中添加以下函数就完成了:]
componentDidMount() {
window.addEventListener("scroll", this.onScroll, false);
}
componentWillUnmount() {
window.removeEventListener("scroll", this.onScroll, false);
}
onScroll = () => {
if (this.hasReachedBottom()) {
this.props.onScrollToBottom();
}
};
hasReachedBottom() {
return (
document.body.offsetHeight + document.body.scrollTop ===
document.body.scrollHeight
);
}
Run Code Online (Sandbox Code Playgroud)
这个答案属于 Brendan,让我们让它发挥作用
export default () => {
const handleScroll = (e) => {
const bottom = e.target.scrollHeight - e.target.scrollTop === e.target.clientHeight;
if (bottom) {
console.log("bottom")
}
}
return (
<div onScroll={handleScroll} style={{overflowY: 'scroll', maxHeight: '400px'}} >
//overflowing elements here
</div>
)
}
Run Code Online (Sandbox Code Playgroud)
如果第一个 div 不可滚动,它将不起作用,并且 onScroll 在第一个 div 之后的 div 等子元素中对我不起作用,因此 onScroll 应该位于第一个溢出的 HTML 标记处