音乐可拖拽进度条的实现方法
进度条定位歌曲功能:
- 点击进度条任何位置定位;
- 拖拽进度按钮定位.
相关样式如下:

整体思路:
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 样式
总结拖拽功能的实现思路:
var btnIsClick = false;- progressBtn 绑定 mousedown 事件,当触发时
btnIsClick = true; - 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');

浙公网安备 33010602011771号