效果
用到的一些事件
阻止默认事件 : ev.preventDefault && ev.preventDefault();
获取宽度:getBoundingClientRect().width
点击位置在元素的位置:ev.changedTouches[0].pageX
<template>
<div id="app">
<div class="slider">
<div class="line"></div>
<div class="line ac"></div>
<div class="box" @touchstart="fnStart"></div>
<div class="box as" @touchstart="fnStart"></div>
</div>
</div>
</template>
js
<script>
export default {
methods: {
fnStart(ev) {
// 计算点击位置在元素的坐标
this.disX = ev.changedTouches[0].pageX - ev.target.offsetLeft;
// 获取父节点
this.parent = ev.target.parentNode;
// 获取元素的宽
this.ow = this.parent.getBoundingClientRect().width;
// 计算除了元素的宽盒子还剩下多宽
this.clienw = this.ow - ev.target.getBoundingClientRect().width;
// 获取左边小圆球
this.lcircle = this.parent.children[2];
// 获取右边小圆球
this.rcircle = this.parent.children[3];
// 获取变色条
this.line = this.parent.children[1];
document.ontouchmove = this.fnmove;
document.ontouchend = this.fnend;
},
fnmove(ev) {
// 计算移动的距离
this.ll = ev.changedTouches[0].pageX - this.disX;
// 判断不能让小圆球到盒子外面
if (this.ll < 0) this.ll = 0;
if (this.ll > this.clienw) this.ll = this.clienw;
// 右边线条
if (ev.target.className.indexOf("as") != -1) {
this.line.style.width =this.ll - this.parent.children[2].offsetLeft + "px";
// 右边推动左边小圆球
// 判断如果右边小球移动到左边小于左边小球offsetLeft的距离 如果当前为0 加一个小圆球的宽他们就不会重叠
console.log(this.ll)
if (this.ll < this.lcircle.offsetLeft + 30) {
// 如果this.ll大于左边小球的值 当前this.ll-30就是左边小球left的值
this.ind = this.ll - 30;
console.log(this.ind)
// 判断当前左边位置过等于0 就让他左边的位置等于0 就不会到盒子外面
if (this.ind <= 0) {
this.ind = 0;
}
// 如果this.ll的值小于小圆球的宽 两个圆就会重叠 所以让右边圆的left值为30
if (this.ll < 30) {
this.ll = 30;
}
this.line.style.left = this.ind + "px";
this.lcircle.style.left = this.ind + "px";
}
} else {
// 左线条
// 获取左边的距离
this.line.style.left = this.ll + "px";
// 当前this.ll就是line多出来的宽 如果左边不动 offsetleft的值是300 this.ll是移动的距离
this.line.style.width =
this.parent.children[3].offsetLeft - this.ll + "px";
// 左边推动右边小圆球 要把右边小球+30 不然两个小球就会重合到一起
if (this.ll + 30 > this.rcircle.offsetLeft) {
this.indX = this.ll + 30;
if (this.indX > this.clienw) {
this.indX = this.clienw;
}
// 判断当前移动的距离不能超过 this.clienw-30如果超过就会重叠
if(this.ll>this.clienw-30){
this.ll=this.clienw-30
}
this.line.style.left=this.indX+'px'
this.rcircle.style.left=this.indX+'px'
}
}
ev.target.style.left = this.ll + "px";
},
fnend() {
document.ontouchmove = null;
document.ontouchend = null;
},
},
};
</script>
css样式
<style scoped lang="less">
.slider {
height: 30px;
width: 300px;
background: #999;
position: relative;
margin: auto;
.box {
width: 30px;
height: 30px;
border-radius: 50%;
background: pink;
position: absolute;
}
.box.as {
background: blueviolet;
right: 0;
}
// 线条
.line {
width: 300px;
height: 5px;
background: #eee;
position: absolute;
}
.line.ac {
background: rgb(247, 151, 25);
}
}
</style>