效果
less
.wrap{
padding: 0 30px;
.slider{
position: relative;
height: 50px;
&-tag{
position: absolute;
top: 0;
left: -5%;
width: 50px;
text-align: center;
span{
display: inline-block;
width: 100%;
padding: 3px 0;
background: green;
border-radius: 5px;
position: relative;
color: #fff;
font-size: 12px;
margin-top: 5px;
&:after{
content: '';
position: absolute;
left: 20px;
bottom: -10px;
width: 0px;
height: 0px;
border: 5px solid green;
border-bottom-color: transparent;
border-left-color: transparent;
border-right-color: transparent;
}
}
}
&-line{
position: absolute;
left: 0;
bottom: 0;
width: 100%;
height: 8px;
background: #fff;
border: 1px solid #ddd;
border-radius: 8px;
overflow: hidden;
&-color{
width: 0;
height: 8px;
background-color: green;
}
}
}
}
TEMPLATE
<template>
<div class="wrap">
<div class="slider">
<div
@touchstart='touchStart'
@touchmove='touchMove'
@touchend='touchEnd'
:style="{left: tagrange + '%'}"
class="slider-tag"
ref="slidertag">
<span ref="spannum" >{{range}}%</span>
</div>
<div class="slider-line" ref="sliderline">
<div class="slider-line-color" :style="{width: range + '%'}"></div>
</div>
</div>
</div>
</template>
SCRIPT
<script>
export default {
data () {
return {
range: 0, // 滑动条位置
tagrange: 0, // 标签移动位置
max: 16, //总条数
min: 0, // 最小位置
startX: 0,
startY: 0,
}
},
methods: {
getPergcent(num, total) {
// 求百分比
num = parseFloat(num);
total = parseFloat(total);
if (isNaN(num) || isNaN(total)) {
return "-";
}
return total <= 0 ? "0%" : (Math.round(num / total * 10000) / 100.00);
},
touchStart(event) {
event.preventDefault() //阻止默认事件(长按的时候出现复制)
this.startX = event.changedTouches[0].pageX
this.startY = event.changedTouches[0].pageY
this.touchStartEnd()
},
touchMove(event) {
event.preventDefault()
let moveEndX = event.changedTouches[0].pageX
let moveEndY = event.changedTouches[0].pageY
let X = moveEndX - this.startX
let Y = moveEndY - this.startY
if(this.range <= 100 && this.range >= 0 ){
if (Math.abs(X) > Math.abs(Y) && X > 0) {
this.range ++
this.tagrange ++
} else if (Math.abs(X) > Math.abs(Y) && X < 0) {
this.range --
this.tagrange --
} else if (Math.abs(Y) > Math.abs(X) && Y > 0) {
console.log('top 2 bottom')
} else if (Math.abs(Y) > Math.abs(X) && Y < 0) {
console.log('bottom 2 top')
} else {
console.log('just touch')
}
}
},
touchEnd() {
this.touchStartEnd()
},
countAnimate(num) {
// 计算滑动位置
const tagw = this.$refs.slidertag.clientWidth/2
const linew = this.$refs.sliderline.clientWidth
const leftw = this.getPergcent(tagw, linew)
this.range = this.tagrange = this.getPergcent(num, this.max)
this.tagrange = this.tagrange-leftw
},
touchStartEnd() {
const tagw = this.$refs.slidertag.clientWidth/2
const linew = this.$refs.sliderline.clientWidth
const leftw = this.getPergcent(tagw, linew)
if(this.range < 0){
this.range = 0
this.countAnimate(this.min)
}
if(this.range > 100){
this.range = 100
this.countAnimate(this.max)
}
}
},
mounted() {
this.countAnimate(9)
}
}
</script>