手搓跑马灯

137 阅读1分钟

好久没写走马灯了,往常都直接使用组建,今天碰巧不太赶时间,决定手搓一个跑马灯

准备一点html


  <div id="container">
    <div class="handler left"></div>
    <div class="handler right"></div>
    <div class="item">1</div>
    <div class="item">2</div>
    <div class="item">3</div>
    <div class="item">4</div>
    <div class="item">5</div>
    <div class="item">6</div>
  </div>

准备一点 css

* {
      margin: 0;
      padding: 0;
    }

    #container {
      position: relative;
      width: 525px;
      height: 256px;
      border: 1px solid #ccc;
      overflow: hidden;
    }

    .item {
      position: absolute;
      width: 175px;
      height: 100%;
      top: 0;
      box-sizing: border-box;
    }

    .item:nth-child(odd) {
      background-color: aquamarine;
    }

    .item:nth-child(even) {
      background-color: bisque
    }

    .handler {
      --size: 40px;
      position: absolute;
      z-index: 999;
      top: calc(50% - var(--size) * 0.5);
      width: var(--size);
      height: var(--size);
      background-color: #ccc;
      border-radius: var(--size);
      display: none;
    }

    #container:hover .handler {
      display: block;
    }

    .handler.left {
      left: 0;
    }

    .handler.right {
      right: 0
    }

初始化布局


    // 获取元素的 style 键值对
    function getStyle(element) {
      if (window.getComputedStyle) {
        return window.getComputedStyle(element, null)
      }
      return element.currentStyle.style
    }

    const container = document.getElementById("container");
    const items = Array.from(container.getElementsByClassName("item"));

    const containerWidth = parseInt(getStyle(container).width)
    const width = parseInt(getStyle(items[0]).width)
    let totalWidth = items.length * width

    // 初始化布局
    items.forEach(function (item, index) {
      item.style.left = width * index + 'px'
    })

完成后界面是这样的

image.png

实现关键函数


let done = false
let dis = -1

function move(timeStamp) {
  if (done || containerWidth >= totalWidth) {
    return
  }

  items.forEach(item => {
    var left = parseInt(item.style.left) + dis
    
    // 边界处理
    if (dis < 0) {
       // 当图像从右往左运动离开视野时,则将元素调整至末尾
      if (left < -width) {
        left = totalWidth - width
      }
    } else {
     // 当元素从左往右运动至离开视野时,则将元素调整至开头
      if (left >= totalWidth - width) {
        left = -width
      }
    }

    item.style.left = left + 'px'
  })

  window.requestAnimationFrame(move)
}

move()

事件处理

container.onmouseenter = function () {
  done = true
}

container.onmouseleave = function () {
  done = false
  move()
}

const ltHandler = container.getElementsByClassName('handler left')
const rtHandler = container.getElementsByClassName('handler right')

ltHandler[0].onmouseenter = function () {
  // 移入控制按钮,移动速度加倍 
  dis = 2
  done = false
  move()
}

ltHandler[0].onmouseleave = function () {
  dis = -1
  done = true
}

rtHandler[0].onmouseenter = function () {
  dis = -2
  done = false
  move()
}

rtHandler[0].onmouseleave = function () {
  dis = -1
  done = true
}

最终效果 image.png