JSFiddle - React, Tailwind, and code Playground

by FiNGAHOLiC

HTML

<div class="status"></div>
<div class="power"></div>

<div class="box"></div>
<div class="box"></div>
<div class="box"></div>
<div class="box"></div>
<div class="box"></div>
<div class="box"></div>
<div class="box"></div>
<div class="box"></div>
<div class="box"></div>
<div class="box"></div>
<div class="box"></div>
<div class="box"></div>
<div class="box"></div>
<div class="box"></div>
<div class="box"></div>
<div class="box"></div>
<div class="box"></div>
<div class="box"></div>
<div class="box"></div>
<div class="box"></div>
<div class="box"></div>
<div class="box"></div>
<div class="box"></div>
<div class="box"></div>
<div class="box"></div>
<div class="box"></div>
<div class="box"></div>
<div class="box"></div>
<div class="box"></div>
<div class="box"></div>
<div class="box"></div>
<div class="box"></div><div class="box"></div>
<div class="box"></div>
<div class="box"></div>
<div class="box"></div>
<div class="box"></div>
<div class="box"></div>
<div class="box"></div>
<div class="box"></div>
<div class="box"></div>
<div class="box"></div>
<div class="box"></div>
<div class="box"></div>
<div class="box"></div>
<div class="box"></div>
<div class="box"></div>
<div class="box"></div>
<div class="box"></div>
<div class="box"></div>
<div class="box"></div>
<div class="box"></div>
<div class="box"></div>
<div class="box"></div>
<div class="box"></div>
<div class="box"></div>
<div class="box"></div>
<div class="box"></div>
<div class="box"></div>
<div class="box"></div>
<div class="box"></div>
<div class="box"></div>
<div class="box"></div>
<div class="box"></div><div class="box"></div>
<div class="box"></div>
<div class="box"></div>
<div class="box"></div>
<div class="box"></div>
<div class="box"></div>
<div class="box"></div>
<div class="box"></div>
<div class="box"></div>
<div class="box"></div>
<div class="box"></div>
<div class="box"></div>
<div class="box"></div>
<div class="box"></div>
<div class="box"></div>
<div class="box"></div>
<div...

SCSS

.power {
  height: 0;
  overflow: hidden;
}

.box {
  background: yellow;
  height: 200px;
  margin: 0 auto;
  transition: background-color 2s ease-out;
  width: 200px;
  &--inside {
    background-color: red;
  }
  & + & {
    margin-top: 10px;
  }
}

JavaScript

const clientHeight = document.documentElement.clientHeight;
const targets = document.querySelectorAll('.box');

// すごい重い処理
const heavyOperation = (num) => {
    const elemStatus = document.querySelector('.status');
    const elemPower = document.querySelector('.power');
    elemStatus.innerHTML = 'start';
    for (let i = 0; i < num; i++){
        const p = document.createElement('p');
        const result = Math.pow(i, i);
        p.innerHTML = result;
        elemPower.appendChild(p);
    }
    elemStatus.innerHTML = 'done';
};

const detectElementIsInViewport = () => {
    Array.from(targets).forEach((target) => {
    		heavyOperation(4);
        const rect = target.getBoundingClientRect();
        if (
            (0 < rect.top && rect.top < clientHeight) ||
            (0 < rect.bottom && rect.bottom < clientHeight) ||
            (rect.top < 0 && clientHeight < rect.bottom)
        ) {
            target.classList.add('box--inside');
        }
    });
}

window.addEventListener('scroll', detectElementIsInViewport, false);
detectElementIsInViewport();