자바스크립트

자바스크립트>스크롤 이벤트

연습노트 2024. 7. 8. 22:26

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

 

그런 재밌는 애니메이션을 만들어봅시다. 

 

설명하다
 
.navbar {
  position : fixed;
  width : 100%;
  z-index : 5
}
.navbar-brand {
  font-size : 30px;
  transition : all 1s;
}

일단 상단메뉴는 상단고정하고 

로고 폰트사이즈를 키운 채로 시작합시다.

그리고 스크롤바를 100px 정도 내리면 폰트사이즈를 줄여봅시다.

그럼 스크롤바를 얼마나 내렸는지 알 수 있어야겠군요 

 

 

 

 

 

 

 

스크롤 이벤트리스너 

 

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

스크롤바를 조작하면 scroll 이벤트가 발생합니다.

그래서 scroll 이벤트리스너를 전체 페이지에 달면

전체 페이지를 스크롤할 때마다 원하는 코드를 실행할 수 있습니다.

진짜 스크롤바 만질 때 마다 '안녕' 출력되나 봅시다. 

 

참고로 window는 그냥 전체 페이지를 의미합니다.

실은 document도 전체 페이지입니다. window가 약간 더 큰 개념인데 scroll 이벤트리스너는 관습적으로 window에 붙임 

 

 

 

 

 

 

스크롤 관련 유용한 기능들

 

스크롤 이벤트리스너안에서 쓰는 유용한 기능들이 몇개 있습니다. 

 

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

window.scrollY 사용하면 현재 페이지를 얼마나 위에서 부터 스크롤했는지 px 단위로 알려줍니다.

매우유용

window.scrollX 는 가로로 얼마나 스크롤했는지 알려줍니다. (가로 스크롤바가 있으면)

 

 

window.scrollTo(0, 100)

window.scrollTo(x, y) 실행하면 강제로 스크롤바를 움직일 수 있습니다.

위 코드는 위에서부터 100px 위치로 스크롤해줍니다.

 

 

window.scrollBy(0, 100)

window.scrollBy(x, y) 실행하면 현재 위치에서부터 스크롤해줍니다.

위 코드는 현재 위치에서부터 +100px 만큼 스크롤해줍니다.

 

 

근데 원래 저거 실행하면 스크롤 위치가 순간이동해야되는데

bootstrap을 설치했을 경우 이상하게 천천히 이동할 수 있습니다.

그게 싫으면 :root { scroll-behavior : auto } 이걸 css 파일 맨 위에 추가합시다. 

 

 

 

 

$(window).on('scroll', function(){
  $(window).scrollTop();
})

jQuery 버전은 더 짧습니다.

$(window).scrollTop() 이거 쓰면 아까처럼 현재 페이지 스크롤 양을 알려줍니다.

근데 간편한건 $(window).scrollTop(100) 이러면 페이지 강제이동도 해줌 

 

필요한건 다 알려줬으니 오늘 숙제로 문제1 기능 완성해오면 됩니다. 

 

 

 

 

 

 

문제 2. 박스 끝까지 스크롤시 알림띄우기

 

<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> 

위 박스를 아무데나 추가합시다.

회원약관인데 이 박스를 끝까지 스크롤하면 alert() 이런걸 띄우고 싶은겁니다.

그럼 코드를 어떻게 짜야할까요 

 

 

div 스크롤바 내린 양 == div 실제높이일 경우 alert 띄워주세요~

이렇게 짜면 될듯요? 근데 

"페이지 스크롤바 내린 양" 구하는건 배웠는데 

"div 박스 스크롤바 내린 양" 구하는 법은 안배웠습니다. 

 

 

 

 

div 박스의 스크롤바 내린 양은 

 

박스를 셀렉터로 찾고 .scrollTop 붙이면 스크롤바를 위에서 부터 얼마나 내렸는지 알려줍니다.

 

설명하다
 
$('.lorem').on('scroll', function(){
  var 스크롤양 = document.querySelector('.lorem').scrollTop;
  console.log(스크롤양);
});

콘솔창에 진짜 출력되는군요.

실은 현재 페이지 스크롤양도 .scrollTop으로 구할 수 있습니다. html 태그 찾아서 .scrollTop 붙이면 됩니다. 

 

 

 

 

 

div 박스 높이 구하는 법 

 

스크롤바가 생긴 박스의 경우 실제 높이같은게 궁금할 수 있습니다. 

박스에 스타일로 넣은 height : 100px 이거 말고 스크롤가능한 실제높이 말입니다.

그럴 땐 셀렉터로 찾아서 .scrollHeight 붙이면 나옵니다.

 

설명하다
 
$('.lorem').on('scroll', function(){
  var 스크롤양 = document.querySelector('.lorem').scrollTop;
  var 실제높이 = document.querySelector('.lorem').scrollHeight;
  console.log(스크롤양, 실제높이);
});

콘솔창에 진짜 출력되는군요.

참고로 박스가 화면에 보이는 부분 높이는 .clientHeight 하면 나옵니다.

document.querySelector('.lorem').scrollHeight; 해보셈 

 

 

 

이제 아까 짜려던 코드를 봅시다. 

 

 

div 스크롤바 내린 양 == div 실제높이일 경우 alert 띄워주세요~

▲ 뭔가 이상한데요 

스크롤바를 끝까지 내려도

스크롤바 내린 양은 188.x

div 실제높이는 288이 나옵니다. 

같다고 비교하면 뭔가 안될 것 같군요.

 

 

 

▲ 왜냐면 스크롤바 내린 양은 진짜 스크롤바 내린 양일 뿐이라 그렇습니다. 

거기에 박스가 보이는 높이는 포함안함 


숙제1. 페이지 스크롤바 100px 내리면 로고 폰트사이즈 작게

 

페이지 스크롤바를 100px 이상 내리면 폰트사이즈 작게만들라고 코드짜면 됩니다.

근데 이 코드를 언제 실행해야되겠습니까 

 

설명하다
 
<script>
  if (window.scrollY > 100) {
    $('.navbar-brand').css('font-size', '20px');
  }
</script>

대충 <script> 태그 안에 적으면 페이지 로드할 때 1회 실행되고 끝날 뿐입니다. 

유저가 페이지 스크롤바 건드릴 때 마다 코드를 실행해줘야 잘되지 않을까요 한번 생각해보십시오. 

 

 

 

설명하다
 
<script>
  $(window).on('scroll', function(){
    if (window.scrollY > 100) {
      $('.navbar-brand').css('font-size', '20px');
    }
  });
</script>

스크롤바 만질 때 마다 코드 실행하고싶으면 스크롤 이벤트리스너 쓰면 됩니다. 

아무튼 이러면 잘 실행됩니다.

다시 스크롤바 올리면 폰트사이즈 크게만들고 싶으면 어떻게 해야할까요 알아서 해봅시다. 

 

 

 

 

 

 

숙제2. 회원약관 박스 거의 끝까지 스크롤하면 alert 띄우기

 

이것은 저번시간에 div 박스 찾아서

div 박스 스크롤양 + 보이는높이 == 실제높이 비교하면 된다고 했습니다.

근데 정확히 일치하는 경우는 잘 없어서 등호말고 부등호 이런거 쓰면 됩니다.

 

 

설명하다
 
$('.lorem').on('scroll', function(){
  var 스크롤양 = document.querySelector('.lorem').scrollTop;
  var 실제높이 = document.querySelector('.lorem').scrollHeight;
  var 높이 = document.querySelector('.lorem').clientHeight;
  if (스크롤양 + 높이 > 실제높이 - 10) {
    alert('다읽음')
  }
});

이러면 바닥~ 10px 위치에 스크롤바가 있을 때 alert를 띄워줍니다. 

진짜인지 10이라는 숫자 맘대로 바꿔가면서 실험해봅시다.

 

 

 

 

 

스크롤 다룰 때 주의점

 

1. 스크롤이벤트리스너 안의 코드는 1초에 60번 이상 실행됩니다. 

그래서 스크롤 이벤트리스너는 많이 달면 성능저하가 일어나니 스크롤바 1개마다 1개만 씁시다. 

 

2. 스크롤이벤트리스너 안의 코드는 1초에 여러번 실행되다보니 바닥체크하는 코드도 여러번 실행될 수 있습니다. 

숙제2에서 alert가 2번 뜨고 그럴 수 있다는 뜻입니다.

그걸 방지하고 싶으면 구글에 검색해보는 것도 나쁘지않습니다. 변수같은걸 활용하면 됩니다. 

 

 

 

 

 

 

현재 페이지를 끝까지 스크롤했는지 체크하려면?

 

숙제2랑 똑같이하면 됩니다.

근데 div 박스를 찾는게 아니라 이번엔 현재페이지를 찾아서 .scrollTop .scrollHeight .clientHeight 붙이면 됩니다. 

현재페이지를 찾으려면 

 

document.querySelector('html').scrollTop;  //현재 웹페이지 스크롤양
document.querySelector('html').scrollHeight; //현재 웹페이지 실제높이
document.querySelector('html').clientHeight; //현재 웹페이지 보이는 높이임

html 태그 찾으면 됩니다. 

.scrollTop 은 너무 길면 window.scrollY 써도 똑같습니다.

 

(주의)

1. 웹페이지 scrollHeight 구할 땐 브라우저마다 아주 약간의 오차가있을 수 있어서 테스트해보는게 좋습니다.

2. 웹페이지 scrollHeight 구하는 코드는 페이지 로드가 완료되고나서 실행해야 정확합니다. 그래서 <body> 끝나기 전에 적는게 좋습니다.