如何检测是否滚动到底部

问题描述 投票:1回答:3

[当用户滚动到底部时,我试图做某事,以下是我在react组件中所做的事情。

注意,这是可行的,但是奇怪的问题是,即使我添加了去抖动功能,当滚动到达底部时,doSomething函数仍然触发两次

我必须将延迟从500扩展到3000或更多,以免发生此问题。为什么会这样,以及如何解决此问题?

componentDidMount() {
    window.addEventListener('scroll', _.debounce(this.handleScroll.bind(this), 500));
}

componentWillUnmount() {
    window.removeEventListener('scroll', _.debounce(this.handleScroll.bind(this), 500));
}

handleScroll() {
    const documentElement = document.documentElement;
    const isScrollToBottom = documentElement.clientHeight + documentElement.scrollTop === documentElement.scrollHeight;

    if (isScrollToBottom) {
        this.doSomething()
    }
}

doSomething(){
    // do something
}
javascript reactjs scroll
3个回答
1
投票

我看到这个问题时正在解决完全相似的问题。这是我的操作方式:

如果调用doSomething,则将初始状态设置为flag:

state = {
  isScrolled: false
}

仅在未滚动时调用doSomething:

if (!isScrolled) {
  this.doSomething()
  // set scrolled to true
  this.setState({isScrolled: true})
}

根据您的情况,您可以结合以下条件:

if (isScrollToBottom && !isScrolled) {

坦白地说,我尝试了几种方法来解决此问题。但是一个小时后我解决了,您的帖子仍在我的窗口标签中。希望您也喜欢这种方法。这样,您甚至不需要使用去抖动方法。


顺便说一句,我正在使用钩子:

const [isScrolled, setIsScrolled] = useState(false)

useEffect(() => {
  doSomething()
  setIsScrolled(true)
},[isScrolled])

0
投票

尝试将您的debouce函数定义为单独的处理程序

handler = _.debounce(() => {
  console.log('foo');
}, 100

然后使用此处理程序是您的addEventlistener和removeEventListener


0
投票

如果您是Mac用户,则快速滚动时,触控板或魔术鼠标可能会引起弹跳。

有时反弹会持续很长时间(可能会持续两秒钟或更长时间,这取决于您滑动触控板的速度。

因此,如果您尝试使用setTimeout异步反跳此问题,则将花费大量的延迟时间。

我尚未执行此问题。但是,如果您的doSomething()是异步函数,则可以按正确的顺序调用该函数。

我“临时”解决这个问题的方式与Bhojendra Rauniyar's答案非常相似。

state = {
  isScrolled: false
}

doSomething(){
    // set isScrolled = false, when async function is done
}

if (isScrollToBottom && !isScrolled) {
  this.setDelay(doSomething, 500)
}

setDelay(callback, time) {
    this.setState({ isScrolled: true });
    setTimeout(
        () => {
            callback();
        },
        time,
    );
}
© www.soinside.com 2019 - 2024. All rights reserved.