【发布时间】:2020-02-13 17:52:55
【问题描述】:
背景:我使用交叉点观察器构建了一个无限滚动器,目的是重用 dom 节点(也称为窗口)。当 div 滚动离开视口的顶部时,它会绝对定位到 div 序列的末尾,反之亦然,对于退出底部的 div。
问题:如果您向上滚动太快,您会完全滚动到 div 之外。同时,如果您向下滚动太快,则不会发生这种情况。很难弄清楚原因。
Codesandbox(原创):https://codesandbox.io/s/cranky-pasteur-wckzm
Codesandbox(更新):https://codesandbox.io/s/infinite-scroll-intersection-observer-p15bm
代码(更新):
/* eslint no-unused-vars: 0 */
/* eslint react-hooks/exhaustive-deps: 0 */
/* eslint no-sequences: 0 */
import React, { useState, useEffect } from "react";
import "./styles.css";
const App = () => {
useEffect(() => {
const divs = document.querySelectorAll('.abc')
const options = {
root: null,
threshold: 0,
rootMargin: '0px'
}
let observer
if (observer) observer.disconnect()
observer = new IntersectionObserver(entries => {
entries.forEach(entry => {
if (entry.isIntersecting || window.pageYOffset === 0) return
entry.target.onclick = function(){console.log(entry)}
const firstDiv = entry.target.parentNode.firstElementChild
const lastDiv = entry.target.parentNode.lastElementChild
const lastDivTopAmount = Number(lastDiv.style.top.split('').slice(0, -2).join(''))
const firstDivTopAmount = Number(firstDiv.style.top.split('').slice(0, -2).join(''))
if (entry.boundingClientRect.top < 0) {
console.log('element intersected top')
firstDiv.style.top = `${lastDivTopAmount+320}px`
firstDiv.parentNode.appendChild(firstDiv)
}
else {
console.log('element intersected bottom')
lastDiv.style.top = `${firstDivTopAmount-320}px`
lastDiv.parentNode.prepend(lastDiv)
}
})
}, options)
divs.forEach(div => {
observer.observe(div)
})
}, [])
return (
<div>
<div className="visibleRows">
<div
style={{top: '0px', backgroundColor: 'blue', height: '320px', width: '580px', outline: '4px solid pink'}}
className="baby-div-1 abc"
/>
<div
style={{top: '320px', backgroundColor: 'red', height: '320px', width: '580px', outline: '4px solid pink'}}
className="baby-div-2 abc"
/>
<div
style={{top: '640px', backgroundColor: 'green', height: '320px', width: '580px', outline: '4px solid pink'}}
className="baby-div-3 abc"
/>
<div
style={{top: '960px', backgroundColor: 'purple', height: '320px', width: '580px', outline: '4px solid pink'}}
className="baby-div-4 abc"
/>
<div
style={{top: '1280px', backgroundColor: 'yellow', height: '320px', width: '580px', outline: '4px solid pink'}}
className="baby-div-5 abc"
/>
<div
style={{top: '1600px', backgroundColor: 'pink', height: '320px', width: '580px', outline: '4px solid pink'}}
className="baby-div-6 abc"
/>
<div
style={{top: '1920px', backgroundColor: 'orange', height: '320px', width: '580px', outline: '4px solid pink'}}
className="baby-div-7 abc"
/>
<div
style={{top:'2240px', backgroundColor: 'cyan', height: '320px', width: '580px', outline: '4px solid pink'}}
className="baby-div-8 abc"
/>
</div>
</div>
);
};
export default App;
样式.css
.abc {
position: absolute;
height: 320px;
width: 580px;
outline: 4px solid pink;
}
【问题讨论】:
-
我认为我无法在运行 Chrome 的 Mac 上重现。向下滚动永远,向上滚动在当前 div 的顶部停止(以慢速和快速速度)。我是不是误会了?
-
@sallf 你在codesandbox上全屏打开demo了吗?如果您尝试在默认代码框窗口中演示代码,则会发生您描述的问题。
-
是的,我在代码框“浏览器”窗口和全屏窗口 (wckzm.csb.app) 中进行了尝试。在这两种情况下,结果都与我上面描述的相同。
-
@salif 我忘了保存css文件。现在就试试。工作吗?
-
是的,我现在可以重现该错误。它是向上滚动到无穷大的期望结果,还是应该在到达页面顶部时停止?
标签: javascript reactjs performance scroll infinite-scroll