在vue项目中使用BetterScroll插件(3)-拖动导航条定位

一、背景需求

上一篇文章中,我们实现了点击字母->定位到相应区域的功能
接下来,我们要实现城市列表随导航条滚动而滚动的功能
页面静态布局如下:
image.png

二、移动端 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方法定位
这部分的内容可以参考上一篇文章

原文地址:https://www.cnblogs.com/baebae996/p/13336117.html