前言
这两天碰评估一个需求:将录音播放器的进度条变成可以拖拽的,进度条+拖拽组合起来这不就是滑块嘛,element-ui中有专门的滑块组件,但是这个进度条本身有自己的业务逻辑,也是简单用progress标签实现的,想了一下还是在process标签基础上先实现一版用于备用。接下来我们来看一下如何将progress变成可拖拽的。
实现
首先我们来看一下process标签,可以用来显示任务的完成度,除了标签公有属性还有以下两个:
- max: 最大值,也就是进度条到最右端的值。
- value:当前进度值,用来展示进度条的完成度。如果没有该属性,就不会显示任何进度。
<progress value="50" max="100">50 %</progress>
目前我们有了进度条,如何实现拖拽效果?我们可以回想一下平时看视频拖拽进度条时右端会有一个点,这就是拖拽点,我们要用这个拖拽点去控制进度条的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';
}
});
总结
以上就是拖拽进度条原生实现的一种方法,样式可以自行修改。日常开发中如果能用滑块组件的话直接用滑块组件会更加方便。