📌 참고
이 게시글은 [프로그래머스] 과제테스트 연습 - 고양이 사진 검색 사이트(https://school.programmers.co.kr/skill_check_assignments/4)를 풀어보며 공부한 내용의 일부를 정리하고 있습니다 :)
📌 clientHeight / offsetHeight / scrollHeight 차이
- clientHeight
- 사용자에게 보여지는 (화면 영역의) element 높이 + 패딩
- 패딩 포함 ⭕ 테두리/스크롤바/마진 포함 ❌
- offsetHeight
- 사용자에게 보여지는 element의 높이 + 패딩 + 테두리 + 스크롤바
- 패딩/테두리/스크롤바 ⭕ 마진 ❌
- scrollHeight
- (보이지 않는 부분까지 포함한) element의 전체 높이 + 패딩 + 테두리 (CSS로 element의 높이를 지정할 때 정해지는 높이)
- 패딩/테두리 ⭕ 마진 ❌
🔽 스크롤바를 특정 요소 끝까지 이동시켰을 경우 다음 이벤트 실행하는 코드
const { clientHeight, scrollTop, scrollHeight } = e.target.scrollElement;
if (clientHeight + scrollTop >= scrollHeight) {
/* 실행할 이벤트 */
}
// 또는
if (scrollHeight - scrollTop === element.clientHeight) {
/* 실행할 이벤트 */
}
📌 window.innerHeight / window.scrollY
- window.innerHeight
- 브라우저에서 실제로 표시되고 있는 영역의 높이
- window.scrollY
- 스크롤이 Y축으로 얼마만큼 이동했는지 나타내는 값
🔽 스크롤바를 화면 끝까지 이동시켰을 경우 다음 이벤트 실행하는 코드
// document.body.scrollHeight: body(페이지 전체)의 높이를 나타냄
if (window.innerHeight + window.scrollY >= document.body.scrollHeight) {
/* 실행할 이벤트 */
}
// 디바운싱 코드
let timer;
if (timer) clearTimeout(timer);
timer = setTimeout(() => {
/* 실행될 이벤트 */
}, 1000);
// 디바운싱을 적용한 스크롤 이벤트 핸들러
if (window.innerHeight + window.scrollY >= document.body.scrollHeight) {
if (timer) clearTimeout(timer);
timer = setTimeout(() => {
console.log("End Of Document");
}, 500);
}
// 쓰로틀링 코드
let timer;
if (!timer) {
timer = setTimeout(() => {
timer = null;
/* 실행될 이벤트 */
}, 1000);
}
// 쓰로틀링을 적용한 스크롤 이벤트 핸들러
if (window.innerHeight + window.scrollY >= document.body.scrollHeight) {
if (!timer) {
timer = setTimeout(() => {
timer = null;
console.log("End Of Document");
}, 500);
}
IntersectionObserver()
생성자callback
: 요소가 교차할 때 실행될 콜백함수options
root
: 타겟 교차할 요소 (기본값 null이자 브라우저 뷰포트)rootMargin
: root의 범위로 CSS의 margin 속성과 유사하게 "10px 20px 30px 40px"
(top, right, bottom, left 순서)와 같이 지정 (기본값은 0)threshold
: 타겟 요소가 얼만큼 보여졌을 때 탐지하고 콜백을 실행할 것인지 지정하는 것으로, 50%를 원할 경우 0.5
와 같이 지정하거나 25% 단위로 요소의 가시성이 변경될 때마다를 원할 경우 [0, 0.25, 0.5, 0.75, 1]
과 같이 배열로 지정할 수 있음 (기본값은 0)IntersectionObserverEntry
객체boundingClientRect
, intersectionRatio
, intersectionRect
, isIntersecting
, isVisible
, rootBounds
, target
, time
속성 포함// 무한 스크롤 예제
// 스크롤할 요소의 마지막에 빈 div를 하나 append한 후 해당 div를 observe한다
const $result = document.querySelector(".resultDiv");
const $end = document.createElement("div");
$result.appendChild($end);
const callback = (entries, observer) => {
entries.forEach((entry) => {
if (entry.isIntersecting) {
/* 실행될 이벤트 */
}
});
}
const observer = new IntersectionObserver(callback, option);
observer.observe($end);
좋은 글 감사합니다.