【记录】实现移动端城市列表,首字母索引跳转
一.效果图
二.实现
功能:
- 点击字母跳转到对应城市列表。
- 字母列表中滑动选择城市列表。
借助better-scroll实现跳转功能, 在vue项目组使用'better-scroll'
// 1.
npm install better-scroll
// 2.在组件中引入
import BScroll from "better-scroll";
// 3.在mounted生命周期中使用,
this.scroll = new BScroll(this.$refs.wrapper);
具体的可参考这篇文章: zhuanlan.zhihu.com/p/27407024
点击字母跳转到对应地区列表
城市列表是根据首字母划分的,通过v-for循环时绑定ref,以便后续获取到对应的地区元素。
<div class="area" v-for="(cityList, key) in cities" :ref="key">
<div class="title border-topbottom">{{ key }}</div>
<div class="city-list">
<ul>
<li v-for="city in cityList" :key="city.id">
{{ city.name }}
</li>
</ul>
</div>
</div>
点击右侧的字母列表时通过事件总线触发自定义事件:
handleLetterclick(e) {
// e.target.innerText:点击的字母
this.$bus.$emit("handleLetterclick", e.target.innerText);
}
在城市列表组件中监听该事件:
methods: {
handleLetter(letter) {
if(letter) {
// 获取到对应城市列表的元素
// this.$refs返回是一个数组,scrollToElement接收的是一个DOM对象
const element = this.$refs[letter][0];
// 跳转
this.scroll.scrollToElement(element);
}
}
},
mounted() {
// better-scroll滚动
this.scroll = new BScroll(this.$refs.wrapper);
// 监听事件
this.$bus.$on("handleLetterclick", this.handleLetter);
},
beforeDestroy() {
this.$bus.$off("handleLetterclick");
}
字母列表中滑动选择城市列表
思路:先计算出字母A距离顶部的距离startY,开始拖动后触摸点的位置为touchY,需要减去头部搜索区域的高度。拖动的距离/每个字母占据高,可得到当前应该在第几个字母上并跳转到对应区域,
const startY = this.$refs["A"][0].offsetTop;
const touchY = e.touches[0].clientY - 73; // 73为搜索区域高度
const index = Math.floor((touchY - this.startY) / 18); // 18为每个li(字母)的高度
if (index >= 0 && index <= this.alphabetList.length) {
// 跳转
this.$bus.$emit("handleLetterclick", this.alphabetList[index]);
}
移动端点击事件失效
在做跳转时遇到个问题,在移动端时click事件只有在首页面有效,其子路由上click事件无效。但在在pc端中click事件均有效。项目使用better-scroll(1.x版本)实现城市列表上下滚动的效果,这会导致无法判断是click事件还是scroll事件,因此需要添加如下配置项:
// 在mounted生命周期中使用,
this.scroll = new BScroll(this.$refs.wrapper,{click:true,tap:true});
完整项目
参考
- 在vue项目组使用better-scroll: zhuanlan.zhihu.com/p/27407024
- 触摸事件: www.wxappclub.com/topic/542 segmentfault.com/q/101000000…
转载自:https://juejin.cn/post/7079764854289989645