[javascript] 13. scroll 이벤트

지렁·2023년 9월 23일
0

📌 다양한 스크롤 이벤트

스크롤 이벤트 리스너 기본

window.addEventListener('scroll', function(){
  console.log('안녕')
});

window 는 그냥 전체 페이지를 의미
document 도 전체 페이지입니다. window 가 약간 더 큰 개념
scroll 이벤트리스너는 관습적으로 window 에 붙임



✅ 페이지 스크롤

1.

window . scrollY

얼마나 스크롤바를 내렸는지 출력
( window.pageYOffeset과 같다 )

window.addEventListener('scroll',function(){
    console.log(window.scrollY);
})

window 가 아닌 일반 div 박스에서의 스크롤 양을 알고 싶으면 scrollTop**

2.

window . scrollTo(x, y)

강제로 (x,y)로 스크롤시킨다

window.addEventListener('scroll',function(){
   console.log(window.scrollTo(0,100));
})

원래 순간이동을 하는게 맞지만 bootstrap 라이브러리로 인해 스크롤을 스무스하게 천천히 처리해준다

➡️ 이걸 원한게 아니라면 css 파일에서 아래 코드 입력

:root{
scroll-behavior:auto
}  

3.

window.scrollBy(0, 100)

현재 위치로부터 (x,y)만큼 이동시킨다

window.addEventListener('scroll',function(){
	console.log(window.scrollBy(0,50))
})

📢 jQuery버전

$(window) . scrollTop( )

이거로 전부 해결 가능하다

◾ 스크롤의 좌표가 궁금한 경우

window.addEventListener('scroll',function(){
	console.log($(window).scrollTop())
})

◾ 스크롤을 이동시키고 싶은 경우

window.addEventListener('scroll',function(){
	$(window).scrollTop(100)
})

✅ div 박스 스크롤

스크롤 내린 양 구하기

박스를 셀렉터로 찾고 .scrollTop 사용

document.querySelector('.lorem').scrollTop

스크롤 바가 생긴 div 박스의 실제 높이 구하기

document.querySelector('.lorem').scrollHeight;


📌 실전

1. 스크롤 바를 100px 내리면 로고 폰트사이즈 작게 만들기

우선 상단 NAV 바를 고정하고 폰트사이즈는 큰 30px로 설정 ➡️ 시작 CSS
그 후 조건문을 이용해 스타일 변경

.navbar{
  position: fixed;
  width:100%;
  z-index:5;
}
.navbar-brand{
font-size:30px;
transition:all 1s;
}
$(window).on('scroll',function(){
    if($(window).scrollTop()>=100){
    $('.navbar-brand').css('fontSize','20px')
    } else {
    $('.navbar-brand').css('fontSize','30px')
    }
})

스크롤을 움직일 때마다 조건문이 작동한다 ✔️


2. 회원약관을 끝까지 읽으면 alert 띄우기

우선 회원약관 박스를 div 를 높이 100px 로 만든다

<div class="lorem" style="width: 100%; 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> 

스크롤을 다 내렸는지를 확인해보기 위하여
스크롤 내린 양 scrollTop 과 div 박스의 전체 높이 scrollHeight 를 비교해보자

$('.lorem').on('scroll',function(){
  let a= document.querySelector('.lorem').scrollTop
  let height= document.querySelector('.lorem').scrollHeight

  // div의 스크롤바 내린 양 == div의 스크롤 가능한 실제 높이
  console.log(a,height)
})

🤔 스크롤의 끝까지 내렸는데도 div박스의 스크롤가능한 높이와 달랐다..!

이유
scrollTop 은 숨겨져있는 전체 div 박스를 기준으로 내가 얼만큼 스크롤 했는지를 나타내는 것이다

<설명 사진>


➡️ 그렇기 때문에 실제로 div 박스의 전체 높이 [숨겨진 부분 + 보여지는 부분 ] 는

내가 스크롤한 양 (scrollTop) + 눈에 보이는 div박스의 높이 (clientHeight) 로 계산하는 것이 맞다

그리고 OS 마다 오차가 있어서 10px 정도 여유를 가지고 체크하는 것이 좋고 등호보다는 부등호로 비교하는 편이 낫다

 <script>
    $('.lorem').on('scroll',function(){
        let myscroll= document.querySelector('.lorem').scrollTop
        let height= document.querySelector('.lorem').scrollHeight
        let realheight= document.querySelector('.lorem').clientHeight

        // div의 스크롤바 내린 양 + div 박스 높이 == div의 실제 높이
        if(myscroll+realheight > height-10){
            alert('회원약관 완료 ')
        }
    })
</script>

다 된 줄 알았으나...

⚠️ 문제 발생

alert가 중복해서 뜬다

이유 : scroll 이벤트는 실시간으로 일어나는 이벤트라 그렇다

✅ 해결방법

alert 상태를 담는 불린 변수를 추가

동작 순서

  1. isAlertShown=false 라는 변수를 만든다
  2. [if] 스크롤을 다 내렸을 때 alert 가 작동하면 true로 바꾸고
  3. [else if] 스크롤을 다시 올리면 false로 바꾼다
	let isAlertShown=false
    $('.lorem').on('scroll',function(){
        let myscroll= document.querySelector('.lorem').scrollTop
        let height= document.querySelector('.lorem').scrollHeight
        let realheight= document.querySelector('.lorem').clientHeight

        // div의 스크롤바 내린 양 == div의 실제 높이
        if(myscroll+realheight>height-10 && !isAlertShown){
            alert('다읽음 ')
            isAlertShown=true
        } else if(myscroll+realheight<height){
            isAlertShown=false
        }
    })


✅ 응용

스크롤 진행바 만들기

<div class="progress-bar" style="width: 100%; height:3px; background:gray;"></div>

<script>
//진행바 스크롤
$(window).on('scroll',function(){
 let scrollTop  = $(window).scrollTop();
 let windowHeight = $(window).height(); // 내가 보이는 화면의 높이
 let documentHeight =  $(document).height(); // 전체 페이지의 높이
 // 스크롤 위치에 따라 진행바의 너비를 계산
 let scrollPercentage = (scrollTop / (documentHeight - windowHeight)) * 100;

 // 진행바의 너비 설정
 $('.progress-bar').css('width', scrollPercentage + '%');     
 })
</script>



정리Time

내가 스크롤한 양
document.querySelector('class').scrollTop < 실제 div 높이 기준>
전체 div 박스 높이
document.querySelector('class').scrollHeight
눈에 보이는 div 박스 높이
document.querySelector('class').clientHeight

<JavaScript에서 요소의 크기 구하기>

높이
- clientHeight : padding을 포함한 높이
- scrollHeight : padding을 포함한 화면 상에 표시되지 않은 콘텐츠를 포함한 높이
- offsetHeight : border, padding, 스크롤 바를 포함한 높이

너비
- clientWidth : padding을 포함한 폭
- scrollWidth : padding을 포함한 화면 상에 표시되지 않은 콘텐츠를 포함한 폭
- offsetWidth : border, padding, 스크롤 바를 포함한 폭


윈도우 사이즈
window.innerWidth :  스크롤 바를 포함하지 않는 창 너비
window.innerHeight : 스크롤 바를 포함하지 않은 창 높이
window.outerWidth : 스크롤 바를 포함, 창의 너비
window.outerHeight :  스크롤 바를 포함한  창의 높이


<jQuery에서 요소의 크기 구하기>

높이
- .height() : 요소 높이만
- .innerHeight() : 요소의 padding을 포함한 높이
- .outerHeight() :  요소의 border, padding 포함한 높이
- .outerHeight(true) : 요소의 margin, border, padding 포함한 높이

너비
- .width() : 요소의 폭만
- .innerWidth() : 요소의 padding을 포함한 폭  
- .outerWidth() : 요소의 border, padding을 포함한 폭
- .outerWidth(true) :  요소의 margin, border, padding을 포함한 폭

만약 요소의 display:none; 일 때 높이 사이즈 취득 여부

 |구할 수 없는 것|구할 수 있는 것 |
 |----|-----|
 |offsetHeight	| height |
 |clientHeight	 |innerHeight |
 	| outerHeight|

[출처] JavaScript, jQuery 에서 높이, 너비 구하는 방법 정리 (하드코딩하는사람들) |
profile
공부 기록 공간 🎈💻

0개의 댓글

관련 채용 정보