html
<div id="range">
<span>0%</span>
<div class="bar">
<div class="progress"></div>
<div class="dot"></div>
</div>
</div>
css
* {
touch-action:manipulation
}
#range {
width:500px;
height:80px;
margin:100px auto;
position:relative;
}
.bar {
width:500px;
height:12px;
border-radius:10px;
background:#e4e7ed;
position:absolute;
top:0;
bottom:0;
left:0;
right:0;
margin:auto;
cursor:pointer;
}
.progress {
width:0;
height:12px;
border-radius:10px;
background:#409eff;
}
.dot {
width:20px;
height:20px;
background:#fff;
border:1px solid #409eff;
position:absolute;
bottom:0;
top:0;
margin:auto 0;
border-radius:50%;
cursor:pointer;
}
js
// 进度条
function slider(obj, maximum = 100) { // maximum最大值默认为100
var range = document.getElementById(obj),
bar = range.getElementsByTagName("div")[0],
progress = bar.children[0],
dot = bar.children[1],
num = range.getElementsByTagName("span")[0];
bar.className = "bar";
progress.className = "progress";
dot.className = "dot";
num.className = "num";
/*
* offsetWidth 获取当前节点的宽度 (width + border + padding)
**/
// 总长度减去原点覆盖的部分
var rest = bar.offsetWidth - dot.offsetWidth;
// 判断是否移动端
if ((!navigator.userAgent.match(/(iPhone|iPod|Android|ios|iOS|iPad|Backerry|WebOS|Symbian|Windows Phone|Phone)/i))) {
// 鼠标按下事件
dot.onmousedown = function(ev) {
/*
* offsetLeft 获取的是相对于父对象的左边距, 返回的是数值, 没有单位
*/
let dotL = dot.offsetLeft;
let e = ev || window.event; //兼容性
/*
* clientX 事件属性返回当事件被触发时鼠标指针向对于浏览器页面(或客户区)的水平坐标。
*/
let mouseX = e.clientX //鼠标按下的位置
window.onmousemove = function(ev) {
let e = ev || window.event;
// 浏览器当前位置减去鼠标按下的位置
let moveL = e.clientX - mouseX; //鼠标移动的距离
// 保存newL是必要的
let newL = dotL + moveL; //left值
// 判断最大值和最小值
if (newL < 0) {
newL = 0;
}
if (newL >= rest) {
newL = rest;
}
// 改变left值
dot.style.left = newL + 'px';
// 计算比例
let bili = newL / rest * maximum;
num.innerHTML = Math.ceil(bili);
progress.style.width = bar.offsetWidth * Math.ceil(bili) / maximum + 'px';
return false; //取消默认事件
}
window.onmouseup = function() {
window.onmousemove = false; //解绑移动事件
return false;
}
return false;
};
// 点击进度条
bar.onclick = function(ev) {
let left = ev.clientX - range.offsetLeft - dot.offsetWidth / 2;
if (left < 0) {
left = 0;
}
if (left >= rest) {
left = rest;
}
dot.style.left = left + 'px';
let bili = left / rest * maximum;
num.innerHTML = Math.ceil(bili);
progress.style.width = bar.offsetWidth * Math.ceil(bili) / maximum + 'px';
return false;
}
} else {
// 触摸事件
dot.ontouchstart = function(ev) {
let dotL = dot.offsetLeft;
let e = ev || window.event; //兼容性
let mouseX = e.touches[0].clientX; //触摸的位置
window.ontouchmove = function(ev) {
let e = ev || window.event;
// 浏览器当前位置减去鼠标按下的位置
let moveL = e.touches[0].clientX - mouseX; //触摸移动的距离
// 保存newL是必要的
let newL = dotL + moveL; //left值
// 判断最大值和最小值
if (newL < 0) {
newL = 0;
}
if (newL >= rest) {
newL = rest;
}
// 改变left值
dot.style.left = newL + 'px';
// 计算比例
let bili = newL / rest * maximum;
num.innerHTML = Math.ceil(bili);
progress.style.width = bar.offsetWidth * Math.ceil(bili) / maximum + 'px';
return false; //取消默认事件
}
window.ontouchend = function() {
window.ontouchmove = false; //解绑移动事件
return false;
}
return false;
};
// 点击进度条
bar.ontouchstart = function(ev) {
let left = ev.touches[0].clientX - range.offsetLeft - dot.offsetWidth / 2;
if (left < 0) {
left = 0;
}
if (left >= rest) {
left = rest;
}
dot.style.left = left + 'px';
let bili = left / rest * maximum;
num.innerHTML = Math.ceil(bili);
progress.style.width = bar.offsetWidth * Math.ceil(bili) / maximum + 'px';
return false;
}
}
}
slider("range");