()
| 68 | |
| 69 | useEffect(() => { |
| 70 | function checkVisibleSections() { |
| 71 | let { innerHeight, scrollY } = window |
| 72 | let newVisibleSections = [] |
| 73 | |
| 74 | for ( |
| 75 | let sectionIndex = 0; |
| 76 | sectionIndex < sections.length; |
| 77 | sectionIndex++ |
| 78 | ) { |
| 79 | let { id, headingRef, offsetRem = 0 } = sections[sectionIndex] |
| 80 | |
| 81 | if (!headingRef?.current) { |
| 82 | continue |
| 83 | } |
| 84 | |
| 85 | let offset = remToPx(offsetRem) |
| 86 | let top = headingRef.current.getBoundingClientRect().top + scrollY |
| 87 | |
| 88 | if (sectionIndex === 0 && top - offset > scrollY) { |
| 89 | newVisibleSections.push('_top') |
| 90 | } |
| 91 | |
| 92 | let nextSection = sections[sectionIndex + 1] |
| 93 | let bottom = |
| 94 | (nextSection?.headingRef?.current?.getBoundingClientRect().top ?? |
| 95 | Infinity) + |
| 96 | scrollY - |
| 97 | remToPx(nextSection?.offsetRem ?? 0) |
| 98 | |
| 99 | if ( |
| 100 | (top > scrollY && top < scrollY + innerHeight) || |
| 101 | (bottom > scrollY && bottom < scrollY + innerHeight) || |
| 102 | (top <= scrollY && bottom >= scrollY + innerHeight) |
| 103 | ) { |
| 104 | newVisibleSections.push(id) |
| 105 | } |
| 106 | } |
| 107 | |
| 108 | setVisibleSections(newVisibleSections) |
| 109 | } |
| 110 | |
| 111 | let raf = window.requestAnimationFrame(() => checkVisibleSections()) |
| 112 | window.addEventListener('scroll', checkVisibleSections, { passive: true }) |
no test coverage detected