I have an element in react, its a modal. Modal is scrollable, and I would want to have number of element that is visible in scroll inside elm
variable.
const Modal = (props) => {
const [elm, setElm] = useState(0)
return (
<p>Current element is: {elm}</p>
<element1/>
<element2/>
<element3/>
<element4/>
)
}
I tried out adding scroll event to modal, and figuring out some way to get scroll position and than compare that position to the element position and return results, but all attempts failed.
CodePudding user response:
I have switched name of the state to page instead of elm, and the answer is:
const Modal = (props) => {
const [page, setPage] = useState(0)
function checkInView(container, element) {
let cTop = container.scrollTop;
let cBottom = cTop container.clientHeight;
let eTop = element.offsetTop;
let eBottom = eTop element.clientHeight;
let isTotal = (eTop >= cTop && eBottom <= cBottom);
let isPartial = (eTop < cTop && eBottom > cTop) || (eBottom > cBottom && eTop < cBottom)
return (isTotal || isPartial);
}
function monitorScroll() {
let elm = document.getElementsByClassName('scrollElementClass')
let pgs = document.getElementsByClassName('pageClass')
elm[0] && elm[0].addEventListener('scroll', (e)=>{
const pages = [...pgs];
const arrOfBools = pages.map(page => checkInView(elm[0], page));
const currentPage = arrOfBools.findIndex(aob => aob === true);
if (currentPage !== page ) {
console.log('triggered')
setPage(currentPage)
}
}
);
}
useEffect(()=>{
monitorScroll()
}, [])
return (
<div className="scrollElementClass">
<p>Current element is: {page}</p>
<element1 className="pageClass"/>
<element2 className="pageClass"/>
<element3 className="pageClass"/>
<element4 className="pageClass"/>
)
}
Basicily, function checkInView
takes heigt of the whole page, compares the position of an element to it, calulates if element is total inside view, and does simple boolean equation:
> let isTotal = (eTop >= cTop && eBottom <= cBottom);
> let isPartial = (eTop < cTop && eBottom > cTop) || (eBottom > cBottom && eTop < cBottom)
afther that, function monitorScroll
takes elements via method getElementByClassName
and inserts "scroll" event listener. Creates array of booleans by mapping pages via checkInView function.
In the end, it simply takes position of true and false inside the array and if position 0 i true that means page 0 is in view, if position 3 is true that means page 3 is in view.