一、背景需求
在 上一篇文章中,我们实现了点击字母->定位到相应区域的功能
接下来,我们要实现城市列表随导航条滚动而滚动的功能
页面静态布局如下:
二、移动端 touch事件的基础知识
常见的触摸事件包括: touchstart、touchmove、touchend
touch对象代表一个触点,每个触点包括位置、大小等属性
通过event.touches[0] 可以获取到 touch对象所在的DOM元素
三、实现思路
1、 为导航条绑定拖动相关的3个事件
<template>
<ul class="list">
<li class="item"
v-for="item of letters"
:key="item"
:ref="item"
@touchstart="handleTouchStart"
@touchmove="handleTouchMove"
@touchend="handleTouchEnd"
@click="handleLetterClick"
>
{{item}}
</li>
</ul>
</template>
2、设定标志位,当拖动开始或结束时,改变标志位的布尔值
data () {
return {
touchStatus: false
}
}
methods: {
handleTouchStart () {
this.touchStatus = true
},
handleTouchMove (event) { },
handleTouchEnd () {
this.touchStatus = false
}
}
3、相关位置的计算:
定义变量 startY 为首字母 'A' 相对于页面头部组件的距离(offsetTop)
定义变量 touchY 为触点所在字母 相对于可视区域顶部的距离(clientY)
一通计算得 触点所在字母的下标为:
(touchY-页面头部组件的绝对高度-startY)/每个字母的绝对高度
handleTouchMove (event) {
if (this.touchStatus) {
const startY = this.$refs['A'][0].offsetTop
const touchY = event.touches[0].clientY
const index = Math.floor((touchY - 79 - this.startY) / 20)
if (index >= 0 && index < this.letters.length) {
this.$emit('change', this.letters[index])
}
}
}
4、兄弟组件接收到触点所在字母,通过scrollToElement方法定位
这部分的内容可以参考上一篇文章