首先在右侧字母列表监听touchstart事件,当事件发生时则执行相应的函数
函数内容
onShortCutTouchStart (e) {
let anchorIndex = getData(e.target, 'index')
this.touch.anchorIndex = anchorIndex
this.$refs.listview.scrollToElement(this.$refs.listgroup[anthorindex], 0)
},
export function getData (el, name, val) {
const prefix = 'data-'
name = prefix + name
if (val) {
return el.setAttribute(name, val)
} else {
return el.getAttribute(name)
}
}
(1)因为列表是用v-for循环渲染得到,所以通过:data-index=“index”绑定一个属性,然后通过getAttribute方法获取每个列表的index。e是事件对象,e.target就是对象的每个item
(2)获取了点击时的index,就可以将这个利用better-scroll里面的scrollToElement方法,进行滚动。给目标元素传入刚刚获得的index,就可以实现滚动。0是滚动时间。this.$refs.listgroup[anthorindex]是要滚动到的目标元素。
this.$refs.listview.scrollToElement(this.$refs.listgroup[anthorindex], 0)
onShortCutTouchStart (e) {
let anchorIndex = getData(e.target, 'index')
let firstTouch = e.touches[0]
this.touch.y1 = firstTouch.pageY
this.touch.anchorIndex = anchorIndex
this._scrollTo(anchorIndex)
},
onShortCutTouchMove (e) {
let firstTouch = e.touches[0]
this.touch.y2 = firstTouch.pageY
let delta = (this.touch.y2 - this.touch.y1) / ANTHOR_HEIGHT | 0
let anthorIndex = parseInt(this.touch.anchorIndex) + delta
this._scrollTo(anthorIndex)
},
_scrollTo (index) {
this.$refs.listview.scrollToElement(this.$refs.listgroup[index], 0)
}
将1中的
this.$refs.listview.scrollToElement(this.$refs.listgroup[anthorindex], 0)
抽象成一个方法,方便调用,节省写代码时间。
(1)首先获取第一次触摸时的pageY和index
(2)然后获取触摸之后每次滑动时的pageY
(3)两个pageY相减就可以知道它滑动的距离
(4)滑动的距离再除以每个字母列表的高度,得到滑动了多少个字母
(5)然后将第一次触摸获取的index加上滑动字母的个数,就可以算出滑到了哪个字母。
(6)最后调用srcoll的srcollToElement方法滑动到对应的元素上。
(7)因为滑动事件需要用到第一次触摸事件时得到的index和pageY,所以我们在creaded生命钩子中设一个this.touch = {}空对象,存储获取的index和pageY。
tips:
(1)
let delta = (this.touch.y2 - this.touch.y1) / ANTHOR_HEIGHT | 0
这条语句后面的或 0是向下取整的意思,也可以使用Math.floor方法。
(2)
在绑定touchmove事件是要阻止冒泡,不然scroll事件也会被触发,即滑动右侧列表时,左侧列表也跟着滑动。
阻止冒泡用@touchmove.stop.prevent
(3)
要给srcoll的probeType属性设为3,否则移动会有问题