我们先上效果图
接着上代码
我们先在components文件夹里新建一个dragRange文件夹,文件夹里按照固定模式新建四个文件,分别是:dragRange.js、dragRange.json、dragRange.wxml、dragRange.wxss
下面是四个文件的代码
// dragRange.js
Component({
properties:{
points: Array,
startIndex: {
type: Number,
default: 0,
},
endIndex: Number,
},
data:{
easyMove: false,
bodyInfo: {},
progressActiveStyle: {
left: 0,
right: 0,
},
leftBtnInfo: {},
rightBtnInfo: {},
hightLightIndex: [],
hightLightClass:[],
hightLightIndexBackUp: [],
bodyWidth: 0,
step: 1,
flag: false,
stylePosition:{
left: 'left:0px;',
right: 'right:0px;',
tenLeft: 'left:-10px;',
tenRight: 'right:-10px;',
leftAddRight: 'left:0px;right:0px;'
}
},
observers:{
"startIndex": function (nv,ov){
if(!this.data.flag)this.init();
this.setData({
flag: true
})
console.log(this.data.flag)
setTimeout(()=>{
this.setData({
flag: false
})
}, 2000)
},
"endIndex": function (nv,ov){
if(!this.data.flag)this.init();
this.setData({
flag: true
})
setTimeout(()=>{
this.setData({
flag: false
})
}, 2000)
},
"progressActiveStyle": function(nv,ov){
const newStylePosition = {
left: `left: ${nv.left}px;`,
right: `right: ${nv.right}px;`,
tenLeft: `left: ${nv.left - 10}px;`,
tenRight: `right: ${nv.right - 10}px;`,
leftAddRight: `left: ${nv.left}px; right: ${nv.right}px;`
}
this.setData({
stylePosition: newStylePosition
})
},
},
ready(){
const query = wx.createSelectorQuery().in(this);
query.select(".progress-bg").boundingClientRect((data) => {
this.data.bodyWidth = data.width;
this.init();
})
.exec();
},
methods:{
computedHightClass(){
const classList = [];
for(let i = 0; i < this.data.points.length; i++){
if(this.data.hightLightIndex.includes(i)){
classList.push('hight-light');
} else {
classList.push('gray-light');
}
}
this.setData({
hightLightClass: classList
})
},
setHightLight() {
const { left, right } = this.data.progressActiveStyle;
this.data.hightLightIndex = [
Math.round(left / this.data.step),
Math.round((this.data.bodyWidth - right) / this.data.step),
];
if (!this.data.hightLightIndexBackUp.length) {
this.data.hightLightIndexBackUp = this.data.hightLightIndex;
}
this.setData({
hightLightIndex: this.data.hightLightIndex
})
this.computedHightClass();
},
setProgress({ left, right }) {
if (left >= 0) {
this.data.progressActiveStyle.left = left;
}
if (right >= 0) {
if (this.data.bodyWidth - right >= 0) {
this.data.progressActiveStyle.right = this.data.bodyWidth - right;
}
}
this.setHightLight();
this.setData({
progressActiveStyle: this.data.progressActiveStyle
})
},
checkMove(name, position) {
const { left, right } = this.data.progressActiveStyle;
const moveRight = position < this.data.bodyWidth - right;
const moveLeft = position > left;
if (this.data.bodyWidth - right - left <= this.data.step) {
if (name === "rightBtnInfo" && moveRight) {
return true;
}
if (name === "leftBtnInfo" && moveLeft) {
return true;
}
}
return false;
},
rightTouchstart(e) {
this.triggerEvent("onTouch", "start");
this.data.easyMove = false;
this.data.rightBtnInfo.diff = e.touches[0].clientX - e.target.offsetLeft - 10;
},
rightTouchmove(e) {
const position = e.touches[0].clientX - this.data.rightBtnInfo.diff;
if (this.checkMove('rightBtnInfo', position)) {
return;
}
this.setProgress({
[this.getKeys('rightBtnInfo')]: position,
});
},
rightTouchend(e) {
this.triggerEvent("onTouch", "end");
this.data.easyMove = true;
const key = this.getKeys('rightBtnInfo');
if (this.data.hightLightIndex[0] >= this.data.hightLightIndex[1]) {
this.data.hightLightIndex = this.data.hightLightIndexBackUp;
} else {
this.data.hightLightIndexBackUp = this.data.hightLightIndex;
}
this.triggerEvent("onChange", {
"right": this.data.points[this.data.hightLightIndex[1]],
"left": this.data.points[this.data.hightLightIndex[0]],
});
this.setProgress({
[key]: this.data.hightLightIndex[key === "left" ? 0 : 1] * this.data.step,
});
},
leftTouchstart(e) {
this.triggerEvent("onTouch", "start");
this.data.easyMove = false;
this.data.leftBtnInfo.diff = e.touches[0].clientX - e.target.offsetLeft - 10;
},
leftTouchmove(e) {
const position = e.touches[0].clientX - this.data.leftBtnInfo.diff;
if (this.checkMove('leftBtnInfo', position)) {
return;
}
this.setProgress({
[this.getKeys('leftBtnInfo')]: position,
});
},
leftTouchend(e) {
this.triggerEvent("onTouch", "end");
this.data.easyMove = true;
const key = this.getKeys('leftBtnInfo');
if (this.data.hightLightIndex[0] >= this.data.hightLightIndex[1]) {
this.data.hightLightIndex = this.data.hightLightIndexBackUp;
} else {
this.data.hightLightIndexBackUp = this.data.hightLightIndex;
}
this.triggerEvent("onChange", {
"left": this.data.points[this.data.hightLightIndex[0]],
"right": this.data.points[this.data.hightLightIndex[1]],
});
this.setProgress({
[key]: this.data.hightLightIndex[key === "left" ? 0 : 1] * this.data.step,
});
},
getKeys(name) {
return {
rightBtnInfo: "right",
leftBtnInfo: "left",
}[name];
},
init() {
const step = this.data.bodyWidth / (this.data.points.length - 1);
const endIndex = this.data.endIndex || this.data.points.length - 1;
this.setData({
step
})
this.setProgress({
left: step * this.data.startIndex,
right: step * endIndex,
});
},
}
})
// dragRange.json
{
"component": true
}
// dragRange.wxml
<view class="drag-range-container">
<view class="progress-container">
<view
class="drag-btn-left drag-btn {{easyMove ? 'easy-btn' : ''}}"
style="{{stylePosition.tenLeft}}"
bindtouchmove="leftTouchmove"
bindtouchstart="leftTouchstart"
bindtouchend="leftTouchend"
bindtouchcancel="leftTouchend"></view>
<view
class="drag-btn-right drag-btn {{easyMove ?'easy-btn' : ''}}"
style="{{stylePosition.tenRight}}"
bindtouchmove="rightTouchmove"
bindtouchstart="rightTouchstart"
bindtouchend="rightTouchend"
bindtouchcancel="rightTouchend"></view>
<view class="progress-bg"></view>
<view
class="progress-active {{easyMove ? 'easy-btn' : ''}}"
style="{{stylePosition.leftAddRight}}"></view>
</view>
<view class="point-list">
<view
class="point-item {{hightLightClass[index]}}"
wx:for="{{points}}"
wx:key="*this">
{{ item }}
</view>
</view>
</view>
// dragRange.wxss
.easy-btn {
transition: all 0.1s linear;
}
.drag-btn {
width: 40rpx;
height: 40rpx;
border-radius: 50rpx;
box-shadow: 0px 2px 4px 0px rgba(0, 0, 0, 0.2);
background: #fff;
z-index: 3;
position: relative;
}
.drag-btn::before {
content: "";
display: block;
position: absolute;
width: 50rpx;
height: 50rpx;
}
.point-item {
color: #666666;
font-size: 24rpx;
width: 80rpx;
}
.point-list {
margin-right: -25rpx;
display: flex;
align-items: center;
justify-content: space-between;
}
.progress-container {
margin-left: 10rpx;
margin-right: 10rpx;
margin-bottom: 20rpx;
height: 45rpx;
position: relative;
}
.progress-bg {
left: 0;
}
.progress-active {
z-index: 2;
background: #ff7600;
border-radius: 50rpx;
height: 10rpx;
}
.progress-bg {
z-index: 1;
width: 100%;
height: 10rpx;
border-radius: 50rpx;
background: #f4f4f4;
}
.progress-bg,
.progress-active,
.drag-btn {
position: absolute;
top: 50%;
transform: translateY(-50%);
}
.hight-light {
color: #ff7600;
font-weight: bold;
}
代码已经贴上去了,可以直接拿过去用
下面就是调用方式
// 在你需要调用这个滑动组件的文件中
// 1.先引入组件
··· // 这里我就不贴代码 了,每个人建的文件地址不一样,根据自己建的文件地址自己引入就可以了
// 2.调用组件
<view class="drag-container"> // 要给.drag-container一个宽度,我是加了一个边框。不然会溢出
<dragRange startIndex="{{getStartIndex}}" endIndex="{{getEndIndex}}" points="{{kWPoints}}" bind:onTouch="onRangeChange" bind:onChange="onRangeChange"></dragRange>
</view>
//js中
data: {
kWPoints: [
"0",
"20",
"40",
"80",
"120",
"160",
"200",
"360",
"480",
"720",
"960",
],
getStartIndex: 0,
getEndIndex: 10,
}
onRangeChange(val){
console.log(val) //这个val就能拿到用户拖拽选择的值了,自己打印出来看看就知道了
},