Intersectionobserver example

by Soya Natsuki

HTML

<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/animate.css/3.7.0/animate.min.css">
<div class="box-list">
  <div class="box tada" data-id="1"></div>
  <div class="box tada" data-id="2"></div>
  <div class="box tada" data-id="3"></div>
  <div class="box tada" data-id="4"></div>
  <div class="box tada" data-id="5"></div>
  <div class="box tada" data-id="6"></div>
  <div class="box tada" data-id="7"></div>
  <div class="box tada" data-id="8"></div>
  <div class="box tada" data-id="9"></div>
  <div class="box tada" data-id="10"></div>
  <div class="box tada" data-id="11"></div>
  <div class="box tada" data-id="12"></div>
  <div class="box tada" data-id="13"></div>
  <div class="box tada" data-id="14"></div>
  <div class="box tada" data-id="15"></div>
</div>

CSS

.box-list {
  max-height: 100vh;
  overflow: scroll;
}

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

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

JavaScript

// global variables
let boxList = []
let scrollTimer = null

// intersection observer options
const option = {
	root: document.querySelector(".box-list"),
  rootMargin: "-50px 0px -50px 0px",
  threshold: [0, 0.25, 0.5, 0.75, 1],
}

// create intersection observer
const io = new IntersectionObserver((entries) => {
  entries.forEach((entry) => {
    if (entry.intersectionRatio >= 0.75) {
    	// add to list
      let tmp = boxList.slice()
      tmp.push(entry.target.dataset.id)
      boxList = [...new Set(tmp)]
    } else {
    	// remove from list
      boxList = boxList.filter((it) => it !== entry.target.dataset.id)
    }
  })
}, option)

// attatch observer
const boxElList = document.querySelectorAll(".box")
boxElList.forEach((el) => {
  io.observe(el)
})

// global scroll event
const boxContainer = document.querySelector(".box-list")
boxContainer.addEventListener("scroll", (e) => {
  console.log(boxList)
  // reset(toggle) animation class
  const boxes = document.querySelector(".tada")
  if (boxes) {
    boxes.classList.remove("tada")
  }
  // reset timer
  if (scrollTimer) {
    clearTimeout(scrollTimer)
  }
  // scroll stop timer
  scrollTimer = setTimeout(() => {
    console.log("time out!")
    boxList.forEach((it) => {
      const box = document.querySelector(`.box[data-id="${it}"]`)
      if (box) {
        box.classList.add("tada")
      }
    })
  }, 1000)
})