Home > Blockchain >  Scroll inside element aware of what element is visible
Scroll inside element aware of what element is visible

Time:10-09

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.

  • Related