需求小能手——推拽进度条

1,647 阅读2分钟

前言

这两天碰评估一个需求:将录音播放器的进度条变成可以拖拽的,进度条+拖拽组合起来这不就是滑块嘛,element-ui中有专门的滑块组件,但是这个进度条本身有自己的业务逻辑,也是简单用progress标签实现的,想了一下还是在process标签基础上先实现一版用于备用。接下来我们来看一下如何将progress变成可拖拽的。

实现

首先我们来看一下process标签,可以用来显示任务的完成度,除了标签公有属性还有以下两个:

  • max: 最大值,也就是进度条到最右端的值。
  • value:当前进度值,用来展示进度条的完成度。如果没有该属性,就不会显示任何进度。
   <progress value="50" max="100">50 %</progress>

image.png

目前我们有了进度条,如何实现拖拽效果?我们可以回想一下平时看视频拖拽进度条时右端会有一个点,这就是拖拽点,我们要用这个拖拽点去控制进度条的value,同时这个拖拽点要跟着进度条的value值同步才可以,所以我们的页面其实很简单就是progress与拖拽点:

     <style>
      body{
        padding: 20px;
      }
      .wrapper{
        position: relative;
      }
      progress {
        width: 200px;
        height: 10px;
        background: royalblue;
        border-radius: 5px;
        border: none;
      }
      progress::-webkit-progress-bar {
        background: royalblue;
        border-radius: 5px;
      }
      progress::-webkit-progress-value {
        background: orange;
        border-radius: 5px;
      }
      #dragPoint {
        width: 10px;
        height: 10px;
        position: absolute;
        top: 10px;
        left: 0;
        background: orange;
        border-radius: 50%;
        cursor: pointer;
      }
    </style>
    <body>
      <div class="wrapper">
      <progress id="progressDom" value="0" max="100"></progress>
      <div id="dragPoint"></div>
    </div>
    </body>

静态页面画出就要考虑拖拽事件了,我们拖拽时需要点击鼠标选择拖拽点,所以拖拽需要用到鼠标事件,拖拽状态与鼠标事件对于如下:

  • 鼠标按下mousedown---拖拽开始
  • 鼠标移动mousemove---拖拽过程
  • 鼠标放开mouseup---拖拽结束
    以上事件都要放到推拽点元素上,接下来让不同的事件完成对应的行为即可:
  • mousedown:为拖拽点添加移动与放开事件。
  • mousemove:在移动时我们要做两件事,第一修改progress中的value值,第二我们要移动拖拽点的位置,让拖拽点与进度条同步,这两步都需要我们计算出进度值,也就是鼠标所在位置减去进度条离可视窗口的位置。
  • mouseup:移动鼠标移动监听事件。
   // 获取元素
    const progress = document.getElementById('progressDom');
    const dragPoint = document.getElementById('dragPoint');
    dragPoint.addEventListener('mousedown', (e) => {
      // 阻止默认事件
      e.preventDefault();

      // 鼠标在拖拽点内的位置 优化偏差
      const offsetX = e.clientX - dragPoint.offsetLeft;

      document.addEventListener('mousemove', moveDragPoint);

      document.addEventListener('mouseup', () => {
        document.removeEventListener('mousemove', moveDragPoint);
      });
      //移动事件
      function moveDragPoint(e) {
        let position = e.clientX - offsetX;
        if (position < 0) {
          position = 0;
        }
        if (position > progress.offsetWidth) {
          position = progress.offsetWidth;
        }
        //修改进度条的值
        const percent = (position / progress.offsetWidth) * 100;
        progress.value = percent;
        //修改拖拽点位置
        dragPoint.style.left = position + 'px';
      }
    });

123.gif

总结

以上就是拖拽进度条原生实现的一种方法,样式可以自行修改。日常开发中如果能用滑块组件的话直接用滑块组件会更加方便。