[当用户滚动到底部时,我试图做某事,以下是我在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
}
我看到这个问题时正在解决完全相似的问题。这是我的操作方式:
如果调用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])
尝试将您的debouce函数定义为单独的处理程序
handler = _.debounce(() => {
console.log('foo');
}, 100
然后使用此处理程序是您的addEventlistener和removeEventListener
如果您是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,
);
}