首先用到的是uni-app获取节点信息
返回一个 SelectorQuery
对象实例。可以在这个实例上使用 select
等方法选择节点,并使用 boundingClientRect
等方法选择需要查询的信息。
Tips:
- 使用
uni.createSelectorQuery()
需要在生命周期mounted
后进行调用。
然后就是@touchstart:手指触摸到一个元素上触发的
@touchmove :手指在元素上移动触发的
TouchList {0: Touch, length: 1} length:1 0:Touch
clientX:65 // 触摸点在浏览器窗口中的横坐标
clientY:18 // 触摸点在浏览器窗口中的纵坐标
force:1 // 触摸点压力大小
identifier:0 // 触摸点唯一标识(ID)
pageX:65 // 触摸点在页面中的横坐标
pageY:18 // 触摸点在页面中的纵坐标
radiusX:11.5 // 触摸点椭圆的水平半径
radiusY:11.5 // 触摸点椭圆的垂直半径
rotationAngle:0 // 旋转角度
screenX:560 // 触摸点在屏幕中的横坐标
screenY:175 // 触摸点在屏幕中的纵坐标
target:div#touchLog 触摸目标 __proto__:Touch __proto__:TouchList
代码:
<view id="body">
<view class="letters">
<view
@touchstart="chooseletter(index,item)"
@touchmove="move($event)"
v-for="(item,index) in letter" :key="index"
:class="currentletter==index?'active':''">{{item}}</view>
</view>
<view>
<scroll-view
scroll-y="true"
:scroll-top="scrolltop"
scroll-with-animation="true"
@scroll="scroll" style="height: 1000rpx;">
<view v-for="(item,index) in city" :key="index" id="citys">
<view class="cityletter">
{{item.letter}}
</view>
<view v-for="(items,indexs) in item.citys" :key="indexs">
{{items}}
</view>
</view>
</scroll-view>
</view>
</view>
export default {
data() {
return {
scrolltop: 0,
letter: ['A', 'B', 'C', 'D', 'E', 'F', 'G'],
city: [{
letter: 'A',
citys: ['安康A', '阿克苏A', '阿拉善A', '安康A', '阿克苏A', '阿拉善A', '安康A', '阿克苏A', '阿拉善A']
},
{
letter: 'B',
citys: ['安康B', '阿克苏B', '阿拉善B', '安康B', '阿克苏B', '阿拉善B', '安康B', '阿克苏B', '阿拉善B', '安康B', '阿克苏B',
'阿拉善B'
]
},
{
letter: 'C',
citys: ['安康C', '阿克苏C', '阿拉善C', '安康C', '阿克苏C', '阿拉善C', '安康C', '阿克苏C', '阿拉善C', '安康C', '阿克苏C',
'阿拉善C', '安康C', '阿克苏C', '阿拉善C'
]
}, {
letter: 'D',
citys: ['安康D', '阿克苏D', '阿拉善D']
},
{
letter: 'E',
citys: ['安康E', '阿克苏E', '阿拉善E', '安康E', '阿克苏E', '阿拉善E']
},
{
letter: 'F',
citys: ['安康F', '阿克苏F', '阿拉善F', '安康F', '阿克苏F', '阿拉善F']
}, {
letter: 'G',
citys: ['安康G', '阿克苏G', '阿拉善G', '安康G', '阿克苏G', '阿拉善G', '安康G', '阿克苏G', '阿拉善G', '安康G', '阿克苏G',
'阿拉善G'
]
}
],
oneheight:'',
lettertop:'',
currentletter:0,
letterbottom:'',
}
},
mounted() {
this.getheight()
},
methods: {
// 获取每个字母距离顶部的高度
getheight() {
let that=this
let theNode = uni.createSelectorQuery().selectAll("#citys")
theNode.boundingClientRect((data) => {
this.city.forEach((item, index) => {
item.top = data[index].top
})
}).exec()
let leter = uni.createSelectorQuery().selectAll(".letters")
leter.boundingClientRect((data) => {
console.log(data)
that.letterbottom=data[0].bottom
that.lettertop=data[0].top
that.oneheight=data[0].height/this.letter.length
}).exec()
},
// 点击字母
chooseletter(letindexs, letitems) {
let cityindex
this.currentletter=letindexs
this.city.forEach((item, index) => {
if (item.letter == letitems) {
this.scrolltop = this.city[index].top
}
})
},
// 滑动字母
move(e){
if(e.touches[0].pageY<=this.lettertop){
this.currentletter=0
this.scrolltop = 0
}else if(e.touches[0].pageY>=this.letterbottom){
this.currentletter=this.letter.length-1
this.scrolltop = this.city[this.city.length-1].top
}else{
let letterindex=((e.touches[0].pageY-this.lettertop)/this.oneheight).toFixed(0)
this.currentletter=letterindex
this.letter.forEach((item,index)=>{
if(index==letterindex){
this.city.forEach((items,indexs)=>{
if(items.letter==item){
this.scrolltop = items.top
}
})
}
})
}
},
// 滑动城市
scroll(e) {
this.city.forEach((item,index)=>{
if((item.top-20)<=e.detail.scrollTop&&this.city[index+1].top-20>=e.detail.scrollTop){
this.letter.forEach((items,indexs)=>{
if(item.letter==items){
this.currentletter=indexs
}
})
}
})
}
}
}
.letters {
position: fixed;
top: 40%;
right: 10rpx;
transform: translate(0, -50%);
z-index: 9;
}
.letters view{
width: 20px;
height: 20px;
text-align: center;
line-height: 20px;
}
.active{
background: red;
border-radius: 50%;
}
预览
第一次写 ,有些地方还需要完善,后续在使用过程中更慢慢改进也欢迎大家的建议