<!DOCTYPE html>

<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Document</title>
<style>
  * {
    margin: 0;
    padding: 0;
    box-sizing: border-box;
  }
  li {
    width: 33.33%;
    border: 1px solid #000;
    font-size: 30px;
    text-align: center;
    position: absolute;
    top: 0;
    left: 0;
    list-style: none;
  }
</style>


<ul></ul>
<script>
  init();
  function init() {
    const ul = document.querySelector("ul");
    for (let index = 0; index < 1000; index++) {
      const li = document.createElement("li");
      li.innerText = index;
      li.style.backgroundColor = getRandomColor();
      li.style.height =
        Math.floor(Math.random() * (200 - 50 + 1) + 50) + "px";
      li.style.opacity = "0";
      ul.appendChild(li);
    }

    function getRandomColor() {
      const color1 = Math.floor(Math.random() * 256);
      const color2 = Math.floor(Math.random() * 256);
      const color3 = Math.floor(Math.random() * 256);
      return `rgb(${color1},${color2},${color3})`;
    }

    setWaterFall();
    function setWaterFall() {
      const lis = [...document.querySelectorAll("li")];
      let index = 0;
      const heightList = [[], [], []];
      const timeId = setInterval(() => {
        const li = lis.shift();
        if (!li) {
          clearInterval(timeId);
          return;
        }
        if (index < 3) {
          const left = index * li.clientWidth + "px";
          li.style.left = left;
          heightList[index].push(li.clientHeight);
        } else {
          // 计算出3个列分别对应的高度 [1,2,3]
          const sumHeightList = heightList.reduce(
            (sumColumnHeight, columnList) => [
              ...sumColumnHeight,
              columnList.reduce((a, b) => a + b, 0),
            ],
            []
          );
          const { minIndex, minHeight } = getMinIndex(sumHeightList);
          const left = minIndex * li.clientWidth + "px";
          const top = minHeight + "px";
          li.style.left = left;
          li.style.top = top;
          heightList[minIndex].push(li.clientHeight);
        }
        li.style.opacity = "1";
        index++;
      }, 500);
    }

    function getMinIndex(arr) {
      let minIndex = 0;
      let minHeight = arr[0];
      for (let index = 0; index < arr.length; index++) {
        const element = arr[index];
        if (minHeight > element) {
          minHeight = element;
          minIndex = index;
        }
      }
      return { minIndex, minHeight };
    }
  }
</script>