scroll event example

by hyeyoon

HTML

<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/animate.css/3.7.0/animate.min.css">
<div class="example">
  <h1 class="title">Scroll Down <span class="arrow">๐Ÿ‘‡</span></h1>
  <div class="box"></div>
  <div class="box"></div>
  <div class="box"></div>
</div>

CSS

.example {
  padding-top: 800px;
  padding-bottom: 300px;
  width: 100%;
  background: #eee;
  position: relative;
}

.title {
  position: absolute;
  top: 10px;
  left: 50%;
  transform: translateX(-50%);
}

.arrow {
  display: inline-block;
  animation: bounce 1s infinite ease;
}

.box {
  margin: 0 auto 200px auto;
  width: 100px;
  height: 100px;
  border-radius: 5px;
  background: #7de2fc linear-gradient(-225deg, #7de2fc 0%, #b9b6e5 100%);
}

.box.tada {
  animation: tada 1s ease;
}

JavaScript

// ํ•ด๋‹น ์š”์†Œ๊ฐ€ viewport ๋‚ด์— ์žˆ๋Š”์ง€ ํ™•์ธํ•˜๋Š” ํ•จ์ˆ˜ 
// ๋Œ€ํ‘œ์ ์ธ ์˜ˆ์‹œ๋กœ ์‚ฌ์šฉ๋˜๊ณ  ์žˆ๋Š” stackoverflow์˜ ์˜ˆ์‹œ๋ฅผ ๊ฐ€์ ธ์™”์Šต๋‹ˆ๋‹ค. 
// https://stackoverflow.com/questions/123999/how-to-tell-if-a-dom-element-is-visible-in-the-current-viewport/7557433#7557433
function isElementInViewport (el) {
  var rect = el.getBoundingClientRect();
  return (
      rect.top >= 0 &&
      rect.left >= 0 &&
      rect.bottom <= (window.innerHeight || document.documentElement.clientHeight) &&
      rect.right <= (window.innerWidth || document.documentElement.clientWidth)
  );
}

// scroll ์ด๋ฒคํŠธ๋ฅผ ์ถ”๊ฐ€ํ•˜๊ณ , ํ•ด๋‹น element์— callback ํ•จ์ˆ˜๋ฅผ ๋“ฑ๋กํ•˜๋Š” ํ•จ์ˆ˜ 
const addEventToEl = (elList) => {
  document.addEventListener('scroll', () => {
  	elList.forEach(el => {
    	if (isElementInViewport(el)) {
      el.classList.add('tada');
      } else {
        el.classList.remove('tada');
      }
    })
  })
}

// ๋™์ž‘์‹œํ‚ฌ elements๋ฆฌ์ŠคํŠธ์— ์ด๋ฒคํŠธ๋ฅผ ๋“ฑ๋ก
const boxElList = document.querySelectorAll('.box');
addEventToEl(boxElList);