왼쪽의 캐러셀이 빨간박스에 닿으면 멈춰보이게 해야한다.
(이해를 돕기위해 Kream서비스에 border를 넣었다.)
현재 fixed인 초록 박스를 삼항연산자로 조건부 스타일링을 해주면 된다.
그러기 위해선 스크롤값을 구하고 일정 스크롤 값에 도달하면 useState hook 을 이용하여 false->true로 상태를 변경한다.
false 일 땐 position:fixed; true 일 땐 position: absolute; 를 주겠다고 계획했다.
const [scrollY, setScrollY] = useState(0);
const [scrollActive, setScrollActive] = useState(false);
const scrollFixed = () => {
if (scrollY > 1350) {
setScrollY(window.pageYOffset);
setScrollActive(true);
} else {
setScrollY(window.pageYOffset);
setScrollActive(false);
}
};
window.pageYOffset을 사용해서 스크롤 Y의 값을 저장한다.
그리고 console.log(scrollY) 를 이용해 scrollY가 어느 값에 도달 했을때 조건부 스타일링을 위한 setScrollActive(true) 를 해줄지 찾아내고 if조건문을 사용해준다.
useEffect(() => {
function scrollListener() {
window.addEventListener("scroll", scrollFixed); }
// window 에서 스크롤을 감시 시작
scrollListener(); // window 에서 스크롤을 감시
return () => {
window.removeEventListener("scroll", scrollFixed); };
// window 에서 스크롤을 감시를 종료
});
useEffect 로 실시간 감시를 해줘야한다, 즉 스크롤이 시작되면 위에 작성한 scrollFixed() 함수를 실행해준다.
주의할 점은 반드시 이벤트리스너를 삭제해 줘야 스크롤할때 2-3번씩 렌더 되지 않는다.
<Box style={{
position : scrollActive ? 'absolute' : 'fixed',
top : scrollActive ? null : '130px' ,
bottom : scrollActive ? '0' : null }} >
인라인스타일을 지양하기 위해 추후 props를 이용해 리펙토링예정.
const scrollFixed = () => {
if (scrollY > 1350) {//생략}
문제가 있다. 단순히 스크롤값만 이용해 조건을 해주다 보니 오른쪽 모달들을 열었을 때 스크롤 값(길이)이 달라지며 빨간 박스에 다다르기도 전에 스타일이 변한다.
어떤 방법을 써야 매번 변하는 스크롤 값에 맞춰 빨간 박스에 도달했을때 초록색 박스가 붙는 것 처럼 보이도록 할수 있을까 많은 고민을 했다.
그러다 useRef를 이용해 변하는 빨간 박스의 높이값을 구해서 구현해보기로 했다.
const containersRef = useRef(null);
const boxRef = useRef(null);
const scrollFixed = () => {
if (scrollY > containersRef.current?.offsetHeight - boxRef.current?.offsetHeight ) {
setScrollY(window.pageYOffset);
setScrollActive(true);
} else {
setScrollY(window.pageYOffset);
setScrollActive(false);
}
};
<Fixed ref={containersRef}>
<Box ref={boxRef} style={{
position : scrollActive ? 'absolute' : 'fixed',
top : scrollActive ? null : '130px' ,
bottom : scrollActive ? '0' : null }} >
</Fixed>
스크롤중 모달이 열려 스크롤의 길이가 달라져도 정상적으로 보인다.
반응형으로 초록색 박스의 높이가 바뀌어도 빨간 박스의 끝에 닿았을때 변한다.
if (scrollY > containersRef.current?.offsetHeight - boxRef.current?.offsetHeight )