0

0

如何使用Vue + better-scroll实现移动端字母索引导航

php中世界最好的语言

php中世界最好的语言

发布时间:2018-05-31 10:13:15

|

2513人浏览过

|

来源于php中文网

原创

这次给大家带来如何使用Vue + better-scroll实现移动端字母索引导航,使用Vue + better-scroll实现移动端字母索引导航的注意事项有哪些,下面就是实战案例,一起来看一下。

Demo:list-view,使用 chrome 手机模式查看。换成手机模式之后,不能滑动的话,刷新一下就 OK 了。

Github: 移动端字母索引导航

效果图

 

配置环境

因为用到的是 vue-cli 和 better-scroll,所以首先要安装 vue-cli,然后再 npm 安装better-scroll。

简单介绍一下 better-scroll:

better-scroll 是一款重点解决移动端(已支持 PC)各种滚动场景需求的插件。它的核心是借鉴的 iscroll 的实现,它的 API 设计基本兼容 iscroll,在 iscroll 的基础上又扩展了一些 feature 以及做了一些性能优化
better-scroll 是基于原生 JS 实现的,不依赖任何框架。它编译后的代码大小是 63kb,压缩后是 35kb,gzip 后仅有 9kb,是一款非常轻量的 JS lib。

除了这两,还使用 scss、vue-lazyload。scss 预处理器,大家都懂,用别的也一样。lazyload 实现懒加载,不用也可以,主要是优化一下体验。

数据直接使用了网易云的歌手榜单,偷懒就直接放在 data 里面了。

CSS 样式我就不贴了,直接看源码就可以了。

实现基本样式

直接使用 v-for 和 双侧嵌套实现歌手列表、以及右侧索引栏。

HTML 结构:

  • {{ group.title }}

    • 如何使用Vue + better-scroll实现移动端字母索引导航 {{ item.name }}

  • {{ item }}

shortcutList 是通过计算属性得到的,取 title 的第一个字符即可。

shortcutList () {
 return this.singers.map((group) => {
  return group.title.substr(0, 1)
 })
}

使用 better-scroll

使用 better-scroll 实现滚动。对了,使用的时候别忘了用 import 引入。

created () {
 // 初始化 better-scroll 必须要等 dom 加载完毕
 setTimeout(() => {
  this._initSrcoll()
 }, 20)
},
methods: {
 _initSrcoll () {
  console.log('didi')
  this.scroll = new BScroll(this.$refs.listView, {
   // 获取 scroll 事件,用来监听。
   probeType: 3
  })
 }
}

使用 created 方法进行 better-scroll 初始化,使用 setTimeout 是因为需要等到 DOM 加载完毕。不然 better-scroll 获取不到 dom 就会初始化失败。

这里把方法写在两 methods 里面,这样就不会看起来很乱,直接调用就可以了。

初始化的时候传入两 probeType: 3,解释一下:当 probeType 为 3 的时候,不仅在屏幕滑动的过程中,而且在 momentum 滚动动画运行过程中实时派发 scroll 事件。如果没有设置该值,其默认值为 0,即不派发 scroll 事件。

给索引添加点击事件和移动事件实现跳转

首先需要给索引绑定一个 touchstart 事件(当在屏幕上按下手指时触发),直接使用 v-on 就可以了。然后还需要给索引添加一个 data-index 这样就可以获取到索引的值,使用 :data-index="index" 。

  • {{ item }}

绑定一个 onShortcutStart 方法。实现点击索引跳转的功能。再绑定一个 onShortcutMove 方法,实现滑动跳转。

created () {
 // 添加一个 touch 用于记录移动的属性
 this.touch = {}
 // 初始化 better-scroll 必须要等 dom 加载完毕
 setTimeout(() => {
  this._initSrcoll()
 }, 20)
},
methods: {
 _initSrcoll () {
  this.scroll = new BScroll(this.$refs.listView, {
   probeType: 3,
   click: true
  })
 },
 onShortcutStart (e) {
  // 获取到绑定的 index
  let index = e.target.getAttribute('data-index')
  // 使用 better-scroll 的 scrollToElement 方法实现跳转
  this.scroll.scrollToElement(this.$refs.listGroup[index])
  // 记录一下点击时候的 Y坐标 和 index
  let firstTouch = e.touches[0].pageY
  this.touch.y1 = firstTouch
  this.touch.anchorIndex = index
 },
 onShortcutMove (e) {
  // 再记录一下移动时候的 Y坐标,然后计算出移动了几个索引
  let touchMove = e.touches[0].pageY
  this.touch.y2 = touchMove
  
  // 这里的 16.7 是索引元素的高度
  let delta = Math.floor((this.touch.y2 - this.touch.y1) / 18)
  // 计算最后的位置
  // * 1 是因为 this.touch.anchorIndex 是字符串,用 * 1 偷懒的转化一下
  let index = this.touch.anchorIndex * 1 + delta
  this.scroll.scrollToElement(this.$refs.listGroup[index])
 }
}

这样就可以实现索引的功能了。

当然这样是不会满足我们的对不对,我们要加入炫酷的特效呀。比如索引高亮什么的~~

移动内容索引高亮

emmm,这个时候就有点复杂啦。但是有耐心就可以看懂滴。

我们需要 better-scroll 的 on 方法,返回内容滚动时候的 Y轴偏移值。所以在初始化 better-scroll 的时候需要添加一下代码。对了,别忘了在 data 中添加一个 scrollY,和 currentIndex (用来记录高亮索引的位置)因为我们需要监听,所以在 data 中添加。

_initSrcoll () {
 this.scroll = new BScroll(this.$refs.listView, {
  probeType: 3,
  click: true
 })
 // 监听Y轴偏移的值
 this.scroll.on('scroll', (pos) => {
  this.scrollY = pos.y
 })
}

然后需要计算一下内容的高度,添加一个 calculateHeight() 方法,用来计算索引内容的高度。

_calculateHeight () {
 this.listHeight = []
 const list = this.$refs.listGroup
 let height = 0
 this.listHeight.push(height)
 for (let i = 0; i < list.length; i++) {
  let item = list[i]
  height += item.clientHeight
  this.listHeight.push(height)
 }
}
// [0, 760, 1380, 1720, 2340, 2680, 2880, 3220, 3420, 3620, 3960, 4090, 4920, 5190, 5320, 5590, 5790, 5990, 6470, 7090, 7500, 7910, 8110, 8870]
// 得到这样的值

然后在 watch 中监听 scrollY,看代码:

watch: {
 scrollY (newVal) {
  // 向下滑动的时候 newVal 是一个负数,所以当 newVal > 0 时,currentIndex 直接为 0
  if (newVal > 0) {
   this.currentIndex = 0
   return
  }
  // 计算 currentIndex 的值
  for (let i = 0; i < this.listHeight.length - 1; i++) {
   let height1 = this.listHeight[i]
   let height2 = this.listHeight[i + 1]
   if (-newVal >= height1 && -newVal < height2) {
    this.currentIndex = i
    return
   }
  }
  // 当超 -newVal > 最后一个高度的时候
  // 因为 this.listHeight 有头尾,所以需要 - 2
  this.currentIndex = this.listHeight.length - 2
 }
}

得到 currentIndex 的之后,在 html 中使用。

给索引绑定 class -->  :class="{'current': currentIndex === index}"

最后再处理一下滑动索引的时候改变 currentIndex。

因为代码可以重复利用,且需要处理边界情况,所以就把

this.scroll.scrollToElement(this.$refs.listGroup[index])

重新写了个函数,来减少代码量。

// 在 scrollToElement 的时候,改变 scrollY,因为有 watch 所以就会计算出 currentIndex
scrollToElement (index) {
 // 处理边界情况
 // 因为 index 通过滑动距离计算出来的
 // 所以向上滑超过索引框框的时候就会 < 0,向上就会超过最大值
 if (index < 0) {
  return
 } else if (index > this.listHeight.length - 2) {
  index = this.listHeight.length - 2
 }
 // listHeight 是正的, 所以加个 -
 this.scrollY = -this.listHeight[index]
 this.scroll.scrollToElement(this.$refs.listGroup[index])
}

lazyload

lazyload 插件也顺便说一下哈,增加一下用户体验。

使用方法

先 npm 安装

在 main.js 中 import,然后 Vue.use

import VueLazyload from 'vue-lazyload'
Vue.use(VueLazyload, {
 loading: require('./common/image/default.jpg')
})

添加一张 loading 图片,使用 webpack 的 require 获取图片。

然后在需要使用的时候,把 :src="" 换成 v-lazy="" 就实现了图片懒加载的功能。

总结

移动端字母索引导航就这么实现啦,感觉还是很有难度的哈(对我来说)。

主要就是使用了 better-scroll 的 on 获取移动偏移值(实现高亮)、scrollToElement 跳转到相应的位置(实现跳转)。以及使用 touch 事件监听触摸,来获取开始的位置,以及滑动距离(计算最后的位置)。

相信看了本文案例你已经掌握了方法,更多精彩请关注php中文网其它相关文章!

推荐阅读:

DeepL
DeepL

DeepL是一款强大的在线AI翻译工具,可以翻译31种不同语言的文本,并可以处理PDF、Word、PowerPoint等文档文件

下载

Vue微信项目按需授权登录实战案例详解

怎样使用angularjs做出购物金额计算工具

相关专题

更多
Java 桌面应用开发(JavaFX 实战)
Java 桌面应用开发(JavaFX 实战)

本专题系统讲解 Java 在桌面应用开发领域的实战应用,重点围绕 JavaFX 框架,涵盖界面布局、控件使用、事件处理、FXML、样式美化(CSS)、多线程与UI响应优化,以及桌面应用的打包与发布。通过完整示例项目,帮助学习者掌握 使用 Java 构建现代化、跨平台桌面应用程序的核心能力。

37

2026.01.14

php与html混编教程大全
php与html混编教程大全

本专题整合了php和html混编相关教程,阅读专题下面的文章了解更多详细内容。

19

2026.01.13

PHP 高性能
PHP 高性能

本专题整合了PHP高性能相关教程大全,阅读专题下面的文章了解更多详细内容。

37

2026.01.13

MySQL数据库报错常见问题及解决方法大全
MySQL数据库报错常见问题及解决方法大全

本专题整合了MySQL数据库报错常见问题及解决方法,阅读专题下面的文章了解更多详细内容。

19

2026.01.13

PHP 文件上传
PHP 文件上传

本专题整合了PHP实现文件上传相关教程,阅读专题下面的文章了解更多详细内容。

16

2026.01.13

PHP缓存策略教程大全
PHP缓存策略教程大全

本专题整合了PHP缓存相关教程,阅读专题下面的文章了解更多详细内容。

6

2026.01.13

jQuery 正则表达式相关教程
jQuery 正则表达式相关教程

本专题整合了jQuery正则表达式相关教程大全,阅读专题下面的文章了解更多详细内容。

3

2026.01.13

交互式图表和动态图表教程汇总
交互式图表和动态图表教程汇总

本专题整合了交互式图表和动态图表的相关内容,阅读专题下面的文章了解更多详细内容。

45

2026.01.13

nginx配置文件详细教程
nginx配置文件详细教程

本专题整合了nginx配置文件相关教程详细汇总,阅读专题下面的文章了解更多详细内容。

9

2026.01.13

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
Node.js 教程
Node.js 教程

共57课时 | 8.6万人学习

Vue 教程
Vue 教程

共42课时 | 6.5万人学习

Go 教程
Go 教程

共32课时 | 3.7万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号