原生js实现无缝滚动

450 阅读1分钟

轮播的实现主要考察编程的逻辑思维能力,具体考察原生dom操作以及定时器的运用等。对不熟悉轮播图实现原理的新手来说还是挺复杂 源码如下:

<!DOCTYPE html>
<html lang="en">
  <head>
    <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>
      .outer {
        width: 500px;
        height: 300px;
        margin: 0 auto;
        position: relative;
        border: 1px solid lightblue;
        position: relative;
        overflow: hidden;
      }
      .inner {
        width: 100%;
        height: 100%;

        display: flex;
        position: relative;
        left: 0px;
        transition: left 1s;
      }
      .inner img {
        width: 100%;
        height: 100%;
        object-fit: cover;
        flex-shrink: 0;
      }

      .outer:hover .btn .btn1 {
        background-color: #add8e6;
        color: #3c7082;
      }

      .btn {
        width: 90%;
        height: 30px;
        position: absolute;
        left: 5%;
        top: 50%;
        transform: translateY(-50%);
        display: flex;
        align-items: center;
        justify-content: space-between;
      }
      .btn1 {
        width: 30px;
        height: 100%;
        border-radius: 4px;
        background-color: rgba(160, 194, 205, 0.3);
        color: rgba(255, 255, 255, 0.3);
        line-height: 30px;
        text-align: center;
        user-select: none;
        cursor: pointer;
      }

      .point {
        display: flex;
        position: absolute;
        bottom: 20px;
        left: 50%;
        transform: translateX(-50%);
      }

      .dot {
        width: 20px;
        height: 20px;
        border-radius: 10px;
        background-color: rgba(255, 255, 255, 0.2);
        margin: 0 10px;
        cursor: pointer;
        user-select: none;
        color: #333;
        text-align: center;
        line-height: 20px;
      }
      .dot-active {
        background-color: rgb(6, 83, 109);
        color: #fff;
      }
    </style>
  </head>
  <body>
    <div class="outer">
      <div class="inner"></div>

      <div class="btn">
        <div class="btn1 left" onclick="leftClick()">&lt;</div>
        <div class="btn1 right" onclick="rightClick()">&gt;</div>
      </div>

      <div class="point">
        <div class="dot" onclick="setIndex(1)">1</div>
        <div class="dot" onclick="setIndex(2)">2</div>
        <div class="dot" onclick="setIndex(3)">3</div>
        <div class="dot" onclick="setIndex(4)">4</div>
      </div>
    </div>
    <script>
      const inner = document.querySelector(".inner");

      function createImg() {
        const arr = [1, 2, 3, 4];
        arr.forEach((item) => {
          const img = document.createElement("img");
          img.src = `./${item}.jpeg`;
          img.alt = `${item}`;
          inner.appendChild(img);
        });
        const img1 = inner.querySelectorAll("img")[0];
        const img4 = inner.querySelectorAll("img")[3];
        inner.insertBefore(img4.cloneNode(true), img1);
        inner.appendChild(img1.cloneNode(true));
      }
      createImg();

      let index = 1;
      let timer = null;

      function autoScroll() {
        timer = setInterval(() => {
          index++;
          fresh();
        }, 3000);
      }
      autoScroll();

      function stopScroll() {
        const outer = document.querySelector(".outer");
        outer.addEventListener("mouseover", () => {
          clearInterval(timer);
        });
        outer.addEventListener("mouseout", () => {
          autoScroll();
        });
      }
      stopScroll();

      function fresh() {
        let dot = document.querySelectorAll(".dot");
        dot.forEach((item) => {
          item.classList.remove("dot-active");
        });

        if (index == 0) {
          dot[3].classList.add("dot-active");
          setTimeout(() => {
            index = 4;
            fresh();
            inner.style.transition = "none 0s";
          }, 1000);
        } else if (index == 5) {
          dot[0].classList.add("dot-active");
          setTimeout(() => {
            index = 1;
            fresh();
            inner.style.transition = "none 0s";
          }, 1000);
        }
        switch (index) {
          case 1:
            dot[0].classList.add("dot-active");
            break;

          case 2:
            dot[1].classList.add("dot-active");
            break;

          case 3:
            dot[2].classList.add("dot-active");
            break;

          case 4:
            dot[3].classList.add("dot-active");
            break;
        }
        inner.style.transition = "left 1s";
        let width = getComputedStyle(inner).width.slice(0, -2);
        inner.style.left = Number(width) * index * -1 + "px";
      }

      fresh();

      function freshWrapper(func) {
        return function () {
          func(...arguments);
          fresh();
        };
      }

      let leftClick = freshWrapper(() => {
        index--;
      });

      let rightClick = freshWrapper(() => {
        index++;
      });

      let setIndex = freshWrapper((idx) => {
        index = idx;
      });
    </script>
  </body>
</html>