横向进度条的实现(可拖拽)
横向进度条是使用挺广的,比如音乐播放器的进度条、上传下载、加载的时候也会用到横向进度条,
下面是播放器的效果图
我就以上面的进度条为例来实现横向的进度条。首先,需要介绍一下H5的新标签progress,
progress
语法
<progress value="22" max="100"></progress>
属性 | 值 | 描述 |
---|---|---|
value | Number | 已完成的任务 |
max | Number | 总任务 |
注意
Internet Explorer 10, Firefox, Opera, Chrome 以及 Safari 6 支持
<progress>
标签。
如果只是根据基本语法来的话我们来看看progress的效果
代码 | 效果 |
---|---|
<progress value="22" max="100"></progress> |
这样的进度条不太好看,因此我们需要对它进行改进,变成自己想要的样子。
看看下面代码
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Document</title>
<style>
.n {
width: 400px;
height: 50px;
background-color: #748ee4;
position: relative;
}
progress {
background: #ccc;
width: 90%;
height: 6px;
left: 5%;
border: 1px solid #ddd;
border-radius: 6px;
cursor: pointer;
position: relative;
}
/* 表示已完成进度背景色,仅兼容谷歌浏览器 */
progress::-webkit-progress-value {
background: #e83e8c;
height: 6px;
border-radius: 6px 0 0 6px;
position: absolute;
top: -1px;
}
/* 表示总任务的背景色 ,仅兼容谷歌浏览器 */
progress::-webkit-progress-bar {
background: #ccc;
}
.progress_btn {
margin-left: 20px;
width: 12px;
height: 12px;
background: #ffffff;
border: 1px solid #ccc;
box-shadow: 0 0 5px 0 #000 0.27;
border-radius: 50%;
position: absolute;
top: 10px;
cursor: pointer;
}
</style>
</head>
<body>
<div class="n">
<progress id="progress" value="0" max="100"> </progress>
<div id="probnt" class="progress_btn"></div>
<!--h5 进度条-->
</div>
</body>
</html>
效果图
这样就实现出我们自己想要的样子了,然后利用原生js的Dom操作来实现进度条的拖拽,在实现进度条的拖拽前我们需要了解拖拽的原理
拖拽(drag)事件
鼠标坐标
- 当鼠标点击移动时,会触发事件,在事件对象中都会保存鼠标当前所在位置的x,y
- 这个坐标有三组
1,当前鼠标位置相对于整个显示屏的左上角坐标 e.screenX e.screenY
2,当前鼠标位置相对于整个文档显示区的左上角坐标 e.clientX e.clientY
3,当前鼠标位置相对于整个显示屏的左上角坐标 e.offsetX e.offsetY
上面的文字不好理解看看下图
知道了怎么获取鼠标坐标之后我们就可以使用鼠标事件onmousedown(当鼠标按下时触发事件),onmousemove(当鼠标移动时触发事件),onmouseup(当按下的鼠标按键被抬起时)来实现拖拽。
代码
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Document</title>
<style>
.n {
width: 400px;
height: 50px;
background-color: #748ee4;
position: relative;
}
progress {
background: #ccc;
width: 360px;
height: 6px;
left: 20px;
border: 1px solid #ddd;
border-radius: 6px;
cursor: pointer;
position: relative;
}
/* 表示已完成进度背景色,仅兼容谷歌浏览器 */
progress::-webkit-progress-value {
background: #e83e8c;
height: 6px;
border-radius: 6px 0 0 6px;
position: absolute;
top: -1px;
}
/* 表示总任务的背景色 ,仅兼容谷歌浏览器 */
progress::-webkit-progress-bar {
background: #ccc;
}
.progress_btn {
margin-left: 20px;
width: 12px;
height: 12px;
background: #ffffff;
border: 1px solid #ccc;
box-shadow: 0 0 5px 0 #000 0.27;
border-radius: 50%;
position: absolute;
top: 10px;
cursor: pointer;
}
</style>
</head>
<body>
<div class="n">
<progress id="progress" value="0" max="100"> </progress>
<div id="probnt" class="progress_btn"></div>
<!--h5 进度条-->
</div>
</body>
<script>
var flag = false; //状态值,按下时才能拖拽
var probnt = document.getElementById("probnt");
var progress = document.getElementById("progress");
var body = document.body;
var offsetX;
probnt.onmousedown = function (e) {
flag = true;
//获取鼠标按下时的位置坐标
offsetX = e.offsetX;
};
body.onmousemove = function (e) {
if (flag) {
//获取当前鼠标的位置
X = e.clientX;
let cl = X - offsetX;
const { left, width } = progress.getBoundingClientRect();
// console.log(left);
// console.log(width);
var ml = cl - left;
if (ml <= 0) {
probnt.style.marginLeft = 20 + "px"; //这里的20是progress的left值
} else if (ml >= width - 12) {
probnt.style.marginLeft = width + 6 + "px"; //这里的20是progress的left值
} else {
probnt.style.marginLeft = 20 + ml + "px"; //这里的20是progress的left值
}
progress.value = ((X - left) / (width - 6)) * 100;
console.log(progress.value);
}
};
body.onmouseup = function () {
flag = false;
};
</script>
</html>
效果如下