原生js拖拽滑动条

78 阅读1分钟

看效果:idiei1.csb.app/
在这里插入图片描述

<!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>
      #qy-bar-wrap {
        width: 434px;
        height: 6px;
        border-radius: 8px;
        position: relative;
      }

      #qy-bar-wrap .bar_container {
        width: 100%;
        height: 100%;
        background-color: #e1e6ed;
        border-radius: 8px;
      }

      #qy-bar-wrap .bar_into {
        height: 100%;
        background-color: #4c6aff;
        border-radius: 8px;
        width: 0;
      }

      #qy-bar-wrap .bar_drag {
        width: 18px;
        height: 18px;
        background: url(https://file.wangjun.work/73r19pdYeSbB827kaeKNRYRuL85XzDdf/icon.png);
        position: absolute;
        background-size: contain;
        cursor: default;
        top: -5px;
        left: 0;
      }

      #qy-bar-wrap .bar_text {
        position: relative;
        left: -9px;
        color: #fff;
        margin-top: 26px;
        width: 38px;
        height: 18px;
        background: #94a6ff;
        border-radius: 4px;
        display: flex;
        justify-content: center;
        align-items: center;
      }

      #qy-bar-wrap .bar_text::before {
        position: absolute;
        left: 0;
        right: 0;
        top: -13px;
        margin: auto;
        content: " ";
        width: 0px;
        height: 0px;
        border-top: 8px solid transparent;
        border-right: 8px solid transparent;
        border-bottom: 8px solid #94a6ff;
        border-left: 8px solid transparent;
      }
    </style>
  </head>
  <body>
    <div
      class="bar_wrap price-account-bar"
      id="qy-bar-wrap"
      drag-bar-id="price-account-bar"
    >
      <!--外包裹元素-->
      <div class="bar_container">
        <!--滑动条-->
        <div class="bar_into"></div>
        <!--滑动痕迹-->
      </div>
      <div class="bar_drag">
        <!--滑块-->
        <div class="bar_text"></div>
        <!--文本-->
      </div>
    </div>
  </body>
  <script>
    function debounce(fn, delay){
        let timeout;
        return function(){
          clearTimeout(timeout)
          timeout = setTimeout(()=>{
            fn.apply(this, arguments)
          },delay)
        }
    }
    class Dragbar {
      constructor(id, total, min) {
        this.total = total;
        this.min = min;
        //获取外包裹元素
        this.eBarWrap = document.querySelector(`[drag-bar-id=${id}]`);
        //获取滑动条
        this.eBarCon = this.eBarWrap.getElementsByClassName("bar_container")[0];
        //获取滑动痕迹元素
        this.eBarInto = this.eBarWrap.getElementsByClassName("bar_into")[0];
        //获取滑块
        this.eBarDrag = this.eBarWrap.getElementsByClassName("bar_drag")[0];
        //获取文本元素
        this.eBarText = this.eBarWrap.getElementsByClassName("bar_text")[0];
        //滑动条的总长度px
        this.nMax = this.eBarCon.offsetWidth - this.eBarDrag.offsetWidth;
        this.init(total);
      }
      setValue(num) {
        if (num <= this.min) {
          num = this.min;
        }
        if (num >= this.total) {
          num = this.total;
        }
        //修改滑块位置
        this.eBarDrag.style.left = (this.nMax / this.total) * num + "px";
        //修改滑动痕迹宽度
        this.eBarInto.style.width =
          (this.nMax / this.total) * num + this.eBarDrag.offsetWidth / 2 + "px";
        //修改文本数值
        this.eBarText.innerHTML = Math.ceil(num);
        //抛出事件
        this.onDrag(Math.ceil(num));
        return this;
      }
      onDrag(num) {}
      init(total = 100) {
        const eBarCon = this.eBarCon;
        const eBarInto = this.eBarInto;
        const eBarDrag = this.eBarDrag;
        const eBarText = this.eBarText;
        eBarText.innerHTML = 0;
        const nMax = eBarCon.offsetWidth - eBarDrag.offsetWidth;
        //滑块添加拖拽事件
        const that = this;
        eBarDrag.addEventListener("mousedown", function (event) {
          //初始化鼠标开始拖拽的点击位置
          var nInitX = event.clientX;
          //初始化滑块位置
          var nInitLeft = this.offsetLeft;
          //页面绑定鼠标移动事件
          document.onmousemove = (event) => {
            //鼠标移动时取消默认行为,避免选中其他元素或文字
            event.preventDefault();
            //获取鼠标移动后滑块应该移动到的位置
            let nX = event.clientX - nInitX + nInitLeft;
            //限制滑块最大移动位置
            if (nX >= nMax) {
              nX = nMax;
            }
            //限制滑块最小移动位置
            if (nX <= 0) {
              nX = 0;
            }
            debounce(that.setValue((nX / that.nMax) * that.total), 3000);
          };
          //鼠标松开绑定事件,取消页面上所有事件
          document.onmouseup = function (event) {
            document.onmousemove = null;
            document.onmouseup = null;
          };
        });
        return;
        //滑动条添加点击事件
        eBarCon.addEventListener("click", function (event) {
          //设置滑动条位置
          var nLeft = this.offsetLeft;
          //获取有定位的父元素
          var eParent = this.offsetParent;
          //循环所有有定位的父元素
          while (eParent) {
            //添加定位父元素offsetLeft值,用于准确定位滑动条与页面左侧的距离
            nLeft += eParent.offsetLeft;
            //再次获取父元素外的定位父元素
            eParent = eParent.offsetParent;
          }
          //计算滑块位置
          var nX = event.clientX - nLeft;
          //修改滑块位置
          eBarDrag.style.left = nX + "px";
          //修改滑动痕迹宽度
          eBarInto.style.width = nX + eBarDrag.offsetWidth / 2 + "px";
          //修改文本数值
          eBarText.innerHTML = Math.ceil((nX / nMax) * 100) / 10;
        });
      }
    }
    const accountDragBar = new Dragbar('price-account-bar', 500, 5)
    accountDragBar.setValue(15)
    accountDragBar.onDrag = function (val) {
        console.log('value===>',val)
  };
  </script>
</html>