- 코드
- 코드 설명
우리가 사용하는 자바스크립트는 브라우저의 요소의 높이나 너비를 계산해주는 관련 객체를 제공해줍니다.
프로그레스바 구현을 위해 document.documentElement
객체에 존재하는 스크롤 관련 속성을 이용하여 유저의 스크롤 위치를 계산하여 프로그레스바를 구현할 수 있었다.
이때 제가 사용한 속성은 scrollTop
, clientHeight
, scrollHeight
입니다.
1) scrollTop
내가 스크롤 하고 있는 위치를 나타내주는 요소라고 생각하면 된다.
2) clientHeight
스크롤바에 있는 컨텐츠 자체의 높이를 뜻합니다. 이 내부 높이는 padding의 값을 포함하고 있지만 margin영역은 포함하지 않습니다.
3) scrollHeight
수직 스크롤바를 사용하지 않고 요소의 컨텐츠를 모두 나타낼 때 필요한 최소 높이의 값과 동일합니다.
간단하게 생각해보면 전체 스크롤이 차지하는 높이에서 현재 내가 차지하고 있는 스크롤의 위치의 비율을 계산하여 css의 width에 적용시키면 쉽게 구현할 수 있다.
따라서 필자는 초반에
// 프로그레스바의 width
const width = ( scrollTop / scrollHeight ) * 100;
으로 계산하였다.
하지만 이럴 경우 정확한 내 스크롤 위치를 나타내지 못하였다.
이 경우에 전체 scrollHeight의 높이에 컨텐츠 길이(clientHeight)가 포함된 길이이기 때문에 전체 스크롤의 길이을 알고 싶다면 scrollHeight - clientHeight를 해주어야 한다.
const { scrollTop, scrollHeight, clientHeight } = document.documentElement;
const height = scrollHeight - clientHeight
const width = ( scrollTop / height ) * 100;
// css 스타일 적용
document.querySelector(`.${className}`).style.width = `${width}%`;
평소 디바운스와 스로틀을 구현할 때 timer의 여부를 판단하기 위해 전역변수로
let timer;
이렇게 두는 것이 굉장히 불편했다.
따라서 이번 미니프로젝트에서 이런 전역변수를 제거하고 모듈화를 할 수있도록 하기 위해서 클로저를 사용하여 디바운스와 스로틀을 구현해보았다.
코드 (util/debounceAndThrottle.js)
export const throttleAndDebounce = () => {
// 쓰로틀링과 디바운스를 체크하기 위한 변수를 만들어줍니다.
let throttleCheck, debounceCheck;
return {
// throttle과 debounce 모두 실행할 콜백 함수와 실행할 주기를 인자로 받습니다.
throttle(callback, milliseconds) {
return function () {
if (!throttleCheck) {
// setTimeout을 이용하여 설정한 주기마다 콜백이 실행될 수 있도록 하였고,
// 실행이 끝난 후에는 다시 throttleCheck를 false로 만들어 주어, 설정한 주기마다 이벤트가 한 번씩만 호출되도록 하였습니다.
throttleCheck = setTimeout(() => {
callback(...arguments);
throttleCheck = false;
}, milliseconds);
}
};
},
debounce(callback, milliseconds) {
return function () {
// clearTimeout을 이용하여 이벤트 발생을 무시해주고,
// 마지막 호출 이후, 일정 시간이 지난 후에 단 한 번만, 이벤트가 호출되도록 하였습니다.
clearTimeout(debounceCheck);
debounceCheck = setTimeout(() => {
callback(...arguments);
}, milliseconds);
};
}
};
};
throttleAndDebounce를 실행하게 되면 throttleCheck
과 debounceCheck
변수를 사용할 수 있게 되고 추가적으로 내부 함수 실행을 통한 callback함수 실행 지연도 가능하게 해줄 수 있습니다.
react 스럽게 개발하기 위해 SPA어플리케이션 형식으로 개발하였습니다;;
- 브라우저 요소 사이즈와 스크롤
https://ko.javascript.info/size-and-scroll- scrollHeight
https://developer.mozilla.org/ko/docs/Web/API/Element/scrollHeight- clientHeight
https://developer.mozilla.org/ko/docs/Web/API/Element/clientHeight