
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 속성으로 인해 블록 형태로 바뀌게 해주었다.