스크롤 이벤트 리스너
스크롤바를 조작하면 scroll 이벤트가 발생한다.
scroll 이벤트 리스너를 전체 페이지에 달면 전체 페이지를 스크롤할 때마다 원하는 코드를 실행할 수 있다.
아래의 코드를 실행하면 스크롤바를 만질 때마다 '안녕'이 출력된다.
window.addEventListener('scroll', function(){
console.log('안녕')
});
(참고) window, document는 전체 페이지를 의미한다. window가 약간 더 큰 개념인데, scroll 이벤트 리스너는 관습적으로 window에 붙임.
스크롤 관련 유용한 기능들
1. scrollY() (= pageYOffset)
window.addEventListener('scroll', function(){
console.log( window.scrollY )
});
- 현재 페이지의 세로 스크롤의 위치를 반환하는 읽기 전용 속성
- 페이지가 얼마나 아래로 스크롤 되었는지를 픽셀 단위로 반환
- window.scrollX() : 현재 페이지의 가로 스크롤의 위치를 반환
scrollY()와 pageYOffset의 차이는?
- pageYOffset이 호환성이 더 좋다.
2.scrollTo()
window.scrollTo(0, 100)
- 문서를 특정 좌표로 직접 스크롤시키는 메서드
- 페이지를 특정 위치로 스크롤하고자 할 때 사용
- 주로 두 개의 매개변수인 x(가로)와 y(세로) 좌표를 설정하여 사용
- 위 코드는 위에서부터 100px 위치로 스크롤을 해 줌
window.scrollTo(0, 100, behavior: 'smooth' )
behavior 옵션을 사용해 스크롤의 애니메이션 효과를 부여할 수도 있다.
3. scrollBy()
window.scrollBy(0, 100)
- 현재 스크롤 위치에서 상대적으로 스크롤시키는 메서드
- 현재 위치에서 상대적인 값을 더하거나 빼서 스크롤을 이동
- 위 코드는 현재 위치에서 아래로 100px 스크롤 함
4. scrollTop()
jQuery 버전은 더 짧다.
$(window).on('scroll', function(){
$(window).scrollTop();
})
- 스크롤 가능한 요소(예: div, body)의 현재 세로 스크롤 위치를 나타내며, 스크롤의 위쪽 경계선으로부터의 픽셀 값을 반환하거나 설정할 수 있다.
- $(window).scrollTop(100) : 스크롤 위치를 100px 아래로 이동시킨다.
<div class="lorem" style="width: 200px; height: 100px; overflow-y: scroll">
Lorem ipsum dolor sit amet, consectetur adipisicing elit. Quae voluptas voluptatum minus praesentium fugit debitis at, laborum ipsa itaque placeat sit, excepturi eius. Nostrum perspiciatis, eligendi quae consectetur praesentium exercitationem.
</div>
위 코드에서 div 박스의 스크롤바를 끝까지 내리면 alert()을 띄우고 싶다면 코드를 어떻게 짜야 할까?
div 스크롤바 내린 양 == div 실제 높이일 경우 alert 띄우기 이런 식으로 짜야 할 것이다.
div 박스의 스크롤바 내린 양은?
셀렉터로 박스를 찾고 .scrollTop을 붙이면 스크롤바를 위에서부터 얼마나 내렸는지 알 수 있다.
$('.lorem').on('scroll', function(){
var 스크롤양 = document.querySelector('.lorem').scrollTop;
console.log(스크롤양);
});
div 박스의 높이는?
스크롤바가 생긴 박스의 경우 실제 높이는 어떻게 구할 수 있을까?
박스에 스타일로 넣은 height: 100px이 아니라 스크롤 가능한 실제 높이 말이다.
그럴 때는 셀렉터로 찾아서 .scrollHeight 붙이면 된다.
5. scrollHeight
$('.lorem').on('scroll', function(){
var 스크롤양 = document.querySelector('.lorem').scrollTop;
var 실제높이 = document.querySelector('.lorem').scrollHeight;
console.log(스크롤양, 실제높이);
});
- 셀렉터.scrollHeight : <div>의 실제 높이
하지만 실행해 보면 스크롤바를 끝까지 내려도 스크롤양과 실제높이가 일치하지 않는다.
"div 스크롤바 내린 양 == div 실제 높이일 경우 alert 띄우기"가 이상하다는 걸 알 수 있다.
스크롤바를 끝까지 내려도 스크롤바를 내린 양은 188.x, div 실제 높이는 288이 나온다.
같다고 비교할 수 없다.
이런 현상이 생기는 이유는 scrollTop의 특징 때문인데, 스크를바 내린 양은 진짜 스크롤바 내린 양일 뿐이라 그렇다.
거기에 박스가 보이는 높이는 포함하지 않는다.
그래서 div 스크롤바 내린 양 + div가 화면에 보이는 높이 == div 실제 높이일 경우 alert 띄우기 이렇게 코드를 짜야 한다.
6. clientHeight
$('.lorem').on('scroll', function(){
var 스크롤양 = document.querySelector('.lorem').scrollTop;
var 실제높이 = document.querySelector('.lorem').scrollHeight;
var 높이 = document.querySelector('.lorem').ClientHeight;
console.log(스크롤양, 실제높이, 높이);
});
- 셀렉터.ClientHeight : 현재 화면에 보이는 콘텐츠의 높이
그러면 이제 div 박스의 스크롤바를 끝까지 내리면 alert()을 띄우는 코드를 어떻게 짤 수 있다.
div 스크롤바 내린 양 + div가 화면에 보이는 높이 == div 실제 높이를 비교하면 되는데, 사실 정확하게 일치하는 경우도 있기 때문에 등호 대신 부등호를 사용해 준다.
$(".lorem").on("scroll", function(){
var 스크롤양 = document.querySelector('.lorem').scrollTop
var 실제높이 = document.querySelector('.lorem').scrollHeight;
var 높이 = document.querySelector('.lorem').clientHeight;
if (스크롤양 + 높이 >= 실제높이){
alert('스크롤 끝');
}
});
스크롤 다룰 때 주의할 점
1. 스크롤 이벤트 리스너 안의 코드는 1초에 60번 이상 실행 된다.
그래서 스크롤 이벤트 리스너는 많이 달면 성능 저하가 일어나니 스크롤바 1개마다 스크롤 이벤트 리스너 1개만 쓰는 것이 좋다.
2. 스크롤 이벤트 리스너 안의 코드는 1초에 여러번 실행되다 보니 바닥 체크하는 코드도 여러번 실행될 수 있다.
위에서 div 박스의 스크롤을 끝까지 내렸을 때 뜨는 alert이 2번 뜰 수도 있다는 그런 뜻이다. 이런 걸 방지하고 싶으면 변수 같은 걸 활용하면 된다.
현재 페이지를 끝까지 스크롤했는지 체크하려면?
위의 div 박스 경우처럼 똑같이 하면 되는데, div가 아니라 현재 페이지를 찾아서 .scrollTop, .scrollHeight, .clientHeight를 붙이면 된다.
document.querySelector('html').scrollTop; //현재 웹페이지 스크롤양
document.querySelector('html').scrollHeight; //현재 웹페이지 실제높이
document.querySelector('html').clientHeight; //현재 웹페이지 보이는 높이임 (=window.scrollY)
(주의)
1. 웹페이지 scrollHeight 구할 때는 브라우저마다 아주 약간의 오차가 있을 수 있어서 테스트 해 보는 것이 좋다.
2. 웹페이지 scrollHeight 구하는 코드는 페이지 로드가 완료되고 나서 실행해야 정확하다. 그래서 <body> 끝나기 전에 적는 것이 좋다.
위의 코드를 다 외우는 것보다
1. 스크롤바 조작할 때마다 코드 실행이 가능하다
2. 박스의 숨겨진 실제 높이도 구할 수 있다
3. 스크롤 내린 양도 구할 수 있다
이런 것들을 이해하고 지나가면 충분하다.
문법은 필요할 때 찾아 쓰면 된다!
* 이 포스팅은 코딩애플 강의를 토대로 작성하였습니다.