x축 쪽으로(수평적으로) 스크롤 할 수 있어야 한다!
- 스크롤이 앞에 있을 때는 뒷부분이 블록 형태로,
- 스크롤이 뒤에 있을 때는 앞부분이 블록 형태로 있어야 한다.
const [scrollX, setScrollX] = useState(0)
const [maxScrollX, setMaxScrollX] = useState(0)
x축으로 스크롤을 할 때, 스크롤값을 담는 state
와 그 스크롤값의 최대값을 담는 state
를 선언한다.
useEffect(() => {
const scrollTag = document.getElementsByClassName('class_list_table_box')[0]
scrollTag.addEventListener('scroll', function () {
// 현재 스크롤 수치값
setScrollX(Math.ceil(this.scrollLeft))
// 현재 스크롤구역의 width에서 스크롤 수치 최대값
setMaxScrollX(scrollTag.scrollWidth - scrollTag.clientWidth)
})
// clean up function
scrollTag.removeEventListener('scroll', function () {
setScrollX(Math.ceil(this.scrollLeft))
setMaxScrollX(scrollTag.scrollWidth - scrollTag.clientWidth)
})
})
스크롤 이벤트가 어디서 어떻게 발생하는지를 useEffect
안의 이벤트리스너를 통하여 조작해 주었다.
class_list_table_box
클래스명의 div에 overflow: scroll;
스크롤 속성을 주었다. 이것을 변수 scrollTag로 지정하였다.addEventListener
를 달았다.addEventListener
를 달았으니 클린업 메서드인 removeEventListener
도 달아주었다.addEventListener
와 removeEventListener
모두 같은 콜백함수를 담고 있다. 이를 리팩토링 하고자 별도로 메서드를 분리해 주었으나, this
때문에 되지 않았던 것으로 기억한다.this
를 selfThis 변수로 담고, 콜백함수에 파라미터로 그대로 받아 시도 -> Xthis
를 잡아서 시도 -> X조금만 더 자세하게 설명해 보자면?!
scrollTag.addEventListener('scroll', function () {
// 현재 스크롤 수치값
setScrollX(Math.ceil(this.scrollLeft))
// 현재 스크롤구역의 width에서 스크롤 수치 최대값
setMaxScrollX(scrollTag.scrollWidth - scrollTag.clientWidth)
})
scrollTag 요소에서 스크롤이 발생한다.
이를 this
로 잡아주고, scrollLeft
특성을 이용하여 스크롤값을 잡아 준다.
scrollLeft
: 스크롤이 오른쪽에서 왼쪽으로 향할 때, 오른쪽 시작점은 0에서부터 출발한다. 요소의 끝으로 갈수록 음수가 나온다고 한다.
(그런데 나는 음수가 아닌, 숫자가 세자리수로 점점 커졌었다..!)
앞쪽의 블록 형태를 위함
소수점으로 아주 세세하게 나오길래, Math.ceil()
메서드로 소수점을 없애고 반올림을 해주었다. 이를 스크롤값 state scrollX
에 담았다.
maxScrollX
state에 담았다. <div className={scrollX >= 300 ? 'scroll_block on' : 'scroll_block 0ff'}>
scroll_block on
으로 클래스명이 바뀌면, postition: sticky
속성으로 인해 블록 형태로 바뀌게 해주었다.<div className={scrollX === 0 || scrollX < maxScrollX ? 'scroll_block on' : 'scroll_block off'}>
scrollX === 0
뒤쪽의 블록 형태는 스크롤을 하지 않을 때부터 (페이지가 처음 로드 될 때부터) 블록 형태로 있어야 한다.
scrollX < maxScrollX
현재 스크롤을 하고 있는 스크롤값이, 최대 스크롤값 (스크롤 영역의 끝)에 도달하기 전까지 블록 형태를 띄워 주어야 한다.
이것도 역시 postition: sticky
속성으로 인해 블록 형태로 바뀌게 해주었다.