原生js实现slider滑块
关键点:
- offsetWidth 获取当前节点的宽度 (width + border + padding)
- offsetLeft 获取的是相对于父对象的左边距
- clientX 事件属性返回当事件被触发时鼠标指针向对于浏览器页面(或客户区)的水平坐标。
html
<div class="content">
<p>0%</p>
<div class="bar">
<div class="progress"></div>
<div class="dot"></div>
</div>
</div>
css
.content {
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
// 获取所有的节点元素
var content = document.getElementsByClassName('content')[0]
var bar = document.getElementsByClassName('bar')[0]
var progress = document.getElementsByClassName('progress')[0]
var dot = document.getElementsByClassName('dot')[0]
var p = document.getElementsByTagName('p')[0]
/*
* offsetWidth 获取当前节点的宽度 (width + border + padding)
**/
// 总长度减去原点覆盖的部分
var rest = bar.offsetWidth - dot.offsetWidth
// 鼠标按下事件
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 * 100
p.innerHTML = Math.ceil(bili) + '%'
progress.style.width = 500*Math.ceil(bili)/100 + 'px';
return false //取消默认事件
}
window.onmouseup = function () {
window.onmousemove = false //解绑移动事件
return false
}
return false
};
// 点击音量条
bar.onclick = function (ev) {
let left = ev.clientX - content.offsetLeft - dot.offsetWidth / 2
if (left < 0) {
left = 0
}
if (left >= rest) {
left = rest
}
dot.style.left = left + 'px'
let bili = left / rest * 100
p.innerHTML =Math.ceil(bili) + '%'
progress.style.width = 500*Math.ceil(bili)/100 + 'px';
return false
}