音乐可拖拽进度条的实现方法

进度条定位歌曲功能:

  • 点击进度条任何位置定位;
  • 拖拽进度按钮定位.

相关样式如下:


整体思路:

1. 元素的注册事件和代码思路

html代码:

<div class="progressBar">
  <div class="currentBar"></div>
  <div class="progressBtn"></div>
</div>

样式代码:

.progressBar {
  width: 100%;
  height: 6px;
  background: #907ac2;
  position: absolute;
  bottom: 0;
  cursor: pointer;
}

.currentBar {
  width: 30%;
  height: 100%;
  background: #302d9f;
}

.progressBtn {
  position: absolute;
  top: -50%;
  width: 12px;
  height: 12px;
  border-radius: 50%;
  border: 4px solid #302d9f;
  background: #fff;
  box-shadow: 0 0 10px #302d9f;

html 元素上注册的事件

    // 进度条整体的鼠标按下事件
    var btnIsClick = false;
    $('.player .controls .progressBar').mousedown(function(e) {
      // console.log('鼠标按下');
      progressMove(e);
    });

    // 鼠标点击按钮事件
    $('.player .controls .progressBtn').mousedown(function(e) {
      // console.log('鼠标按下');
      btnIsClick = true;
    });

    // 鼠标移动事件, 用于拖动
    $('.player .controls .progressBar').mousemove(function(e) {
      // console.log('鼠标正在移动');
      if (btnIsClick) {
        progressMove(e);
      }
    });

    // 鼠标弹起事件,用于释放拖动 (注意:这里是在 document 上注册的)
    $(document).mouseup(function() {
      // console.log('鼠标弹起');
      btnIsClick = false;
    });

注:mouseup事件注册在document对象上,以实现在网页上任何位置释放鼠标键就能结束拖拽事件.

若鼠标弹起事件是注册在进度条上,则当保持鼠标键按下不放,在除了进度条之外的地方上松开.此时可发现,当指针重新移到进度条上时,进度条是会跟着指针变动的.

原因:mouseup事件是注册在进度条上的,鼠标键虽然松开了,但是在进度条以外的地方上松开的,此时进度条并不会监听到mouseup事件的发生,因此进度条仍保持鼠标键按下的状态,progressMove函数依旧会运行.

2. progressMove函数的思路:

距离的比值*歌曲总时长,把该值赋给audio.currentTime

  • 当事件目标对象为 progressBtn, 实现拖拽功能:按钮元素与定位父元素progressBar的距离progressBtn.offsetLeft 与整个进度条 progressBar.offsetWidth
  • 当事件目标对象为 progressBar, 实现点击功能:点击位置距进度条初始端的距离 e.offsetX 与整个进度条

以上相关代码如下:

function progressMove(e) {
  var updateTime;
  if (e.target === $('.progressBtn')[0]) {
    updateTime = ($('.progressBtn')[0].offsetLeft / $('.player .controls .progressBar')[0].offsetWidth) * playStatus.currentTotalTime;
  } else {
    updateTime = (e.offsetX / $('.player .controls .progressBar')[0].offsetWidth) * playStatus.currentTotalTime;
  }
  $('#audio')[0].currentTime = updateTime;
}

3.添加 css 样式

总结拖拽功能的实现思路:

  1. var btnIsClick = false;
  2. progressBtn 绑定 mousedown 事件,当触发时 btnIsClick = true;
  3. progressBar 绑定 mousemove 事件,当触发时,在满足 btnIsClick = true;的条件下,运行progressMove(e);

完整的代码:

<div class="progressBar">
  <div class="currentBar"></div>
  <div class="progressBtn"></div>
</div>
.progressBar {
  width: 100%;
  height: 6px;
  background: #907ac2;
  position: absolute;
  bottom: 0;
  cursor: pointer;
}

.currentBar {
  width: 30%;
  height: 100%;
  background: #302d9f;
}

.progressBtn {
  position: absolute;
  top: -50%;
  width: 12px;
  height: 12px;
  border-radius: 50%;
  border: 4px solid #302d9f;
  background: #fff;
  box-shadow: 0 0 10px #302d9f;
    // 进度条整体的鼠标按下事件
    var btnIsClick = false;
    $('.player .controls .progressBar').mousedown(function(e) {
      // console.log('鼠标按下');
      progressMove(e);
    });

    // 鼠标点击按钮事件
    $('.player .controls .progressBtn').mousedown(function(e) {
      // console.log('鼠标按下');
      btnIsClick = true;
    });

    // 鼠标移动事件, 用于拖动
    $('.player .controls .progressBar').mousemove(function(e) {
      // console.log('鼠标正在移动');
      if (btnIsClick) {
        progressMove(e);
      }
    });

    // 鼠标弹起事件,用于释放拖动 (注意:这里是在 document 上注册的)
    $(document).mouseup(function() {
      // console.log('鼠标弹起');
      btnIsClick = false;
    });

    function progressMove(e) {
      var updateTime;
      if (e.target === $('.progressBtn')[0]) {
        updateTime = ($('.progressBtn')[0].offsetLeft / $('.player .controls .progressBar')[0].offsetWidth) * playStatus.currentTotalTime;
      } else {
        updateTime = (e.offsetX / $('.player .controls .progressBar')[0].offsetWidth) * playStatus.currentTotalTime;
      }
      $('#audio')[0].currentTime = updateTime;
    }


  //添加currentBar的css样式
  $('.player .controls .currentBar').css('width', playStatus.currentTime / playStatus.currentTotalTime * 100 + '%');

  //添加progressBtn的css样式
  $('.player .controls .progressBtn').css('left', playStatus.currentTime / playStatus.currentTotalTime * $('.progressBar')[0].offsetWidth - $('.progressBtn')[0].offsetWidth * 0.5 + 'px');
posted @ 2020-08-10 17:17  EzenLee  阅读(1249)  评论(1)    收藏  举报