微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

Vue + better-scroll 实现移动端字母索引导航功能

vue+ better-scroll 实现移动端歌手列表字母索引导航。算是一个学习笔记吧,写个笔记让自己了解的更加深入一点。

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

Github:

效果

配置环境

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

简单介绍一下 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 结构:

rush:js;">
  • {{ item }}
  • shortcutList 是通过计算属性得到的,取 title 的第一个字符即可。

    { return group.title.substr(0,1) }) }

    使用 better-scroll

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

    { 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" 。

    rush:js;">
  • {{ item }}
  • 绑定一个 onShortcutStart 方法。实现点击索引跳转功能。再绑定一个 onShortcutMove 方法,实现滑动跳转

    { this._initSrcoll() },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 中添加

    { this.scrollY = pos.y }) }

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

    rush:js;"> _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,看代码

    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])

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

    rush:js;"> // 在 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

    rush:js;"> 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 事件监听触摸,来获取开始的位置,以及滑动距离(计算最后的位置)。

    总结

    以上所述是小编给大家介绍的Vue + better-scroll 实现移动端字母索引导航功能。编程之家 jb51.cc 收集整理的教程希望能对你有所帮助,如果觉得编程之家不错,可分享给好友!感谢支持

    版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

    相关推荐


    可以通过min-width属性来设置el-table-column的最小宽度。以下是一个示例: &lt;template&gt; &lt;el-table :data=&quot;tableData&quot;&gt; &lt;el-table-column prop=&quot;item_no&q
    yarn dev,当文件变动后,会自动重启。 yanr start不会自动重启 nodemon会监听文件变动,跟yarn dev和yarn start无关。
    ref 用于创建一个对值的响应式引用。这个值可以是原始值(如数字或字符串)或对象。当 ref 的值发生变化时,Vue 会自动更新 DOM 或任何其他使用该 ref 的响应式依赖。 使用示例: import { ref } from &#39;vue&#39;; const count = ref(0
    通过修改 getWK005 函数来实现这一点。这里的 query 参数就是发送 GET 请求时的查询参数。你可以将需要的条件作为 query 对象的属性传递进去。比如,如果你想要按照特定的条件查询信息,你可以在调用 getWK005 函数时传递这些条件。例如: getWK005({ conditio
    &lt;el-form-item label=&quot;入库类型&quot; prop=&quot;mt_type&quot;&gt; &lt;el-select v-model=&quot;form.mt_type&quot; filterable placeholder=&quot;请选择&q
    API 变动 样式类名变化: 一些组件的样式类名有所变动,可能需要更新你的自定义样式。 事件名和属性名变化: 某些组件的事件名和属性名发生了变化,需要检查 Element Plus 文档 以了解详细信息。 使用 setup 函数: 在 Vue 3 中,可以使用 Composition API(如 s
    安装和引入方式 Element UI (Vue 2): // main.js import Vue from &#39;vue&#39;; import ElementUI from &#39;element-ui&#39;; import &#39;element-ui/lib/theme-cha
    排查400 (Bad Request)和解决这个问题,可以按照以下步骤进行: 检查URL和端点:确保URL http://127.0.0.1:8008/basicApp/BS037HModel/ 是正确的,并且该端点在服务器上存在。 检查请求参数:确认发送请求时的任何参数都是正确的,包括查询参数、请
    在 Vue.js 中,&lt;template&gt; 标签是一种特殊的标签,它用于定义组件的模板,但不会直接渲染为 HTML 元素。它的主要用途是在编写组件和使用插槽时提供灵活的模板定义。以下是关于 &lt;template&gt; 标签的一些关键概念和使用示例。 基本用法 组件模板:在单文件组件
    el-config-provider是Element Plus库中的一个组件,用于提供全局的配置。它是Element Plus在2.0版本中引入的新组件。 el-config-provider组件的作用是允许你在应用程序中统一配置Element Plus的一些全局属性和样式,这些配置将被应用于所有E