前言:在学习黄轶老师的《Vue.js高仿饿了么外卖App》课程中接触到了better-scroll第三方JavaScript组件库,这是黄轶老师自己基于iscroll重写的库。这里结合黄轶老师的知乎文章和Vue2.0项目对better-scroll的具体应用,只作为学习,对其中的原理和应用步骤做一个梳理。


            移动端项目列表滚动的需求

竖直滚动:

横向滚动:

           什么是better-scroll

better-scroll 是一个移动端滚动的解决方案,它是基于 iscroll 的重写,它和 iscroll 的主要区别在这里。better-scroll 也很强大,不仅可以做普通的滚动列表,还可以做轮播图、picker 等等。

  • 安装better-scroll
npm install better-scroll --save

  

           better-scroll 的滚动原理

      浏览器的滚动原理:

浏览器的滚动条大家都会遇到,当页面内容的高度超过视口高度的时候,会出现纵向滚动条;当页面内容的宽度超过视口宽度的时候,会出现横向滚动条。也就是当我们的视口展示不下内容的时候,会通过滚动条的方式让用户滚动屏幕看到剩余的内容。

better-scroll的滚动原理:

  • 常用的html结构
div class="wrapper">
<ul class="content">
<li></li>
<li></li>
<li></li>
<li></li>
</ul>
</div>

当 content 的高度不超过父容器的高度,是不能滚动的,而它一旦超过了父容器的高度,我们就可以滚动内容区了,这就是 better-scroll 的滚动原理

  • 初始化better-scroll  
 import BScroll from 'better-scroll'
let wrapper = document.querySelector('.wrapper')
let scroll = new BScroll(wrapper, {})

关于参数:better-scroll 对外暴露了一个 BScroll 的类,我们初始化只需要 new 一个类的实例即可。

第一个参数就是我们 wrapper 的 DOM 对象,第二个是一些配置参数,具体参考 better-scroll 的文档。  

better-scroll 的初始化时机:

  • 初始化时机很重要,因为它在初始化的时候,会计算父元素和子元素的高度和宽度,来决定是否可以纵向和横向滚动。因此,我们在初始化它的时候,必须确保父元素和子元素的内容已经正确渲染了。如果没有办法滑动,那就是初始化的时机不对。
  • 如果子元素或者父元素 DOM 结构发生改变的时候,必须重新调用 scroll.refresh() 方法重新计算来确保滚动效果的正常。
  • 所以常见的 better-scroll 不能滚动的原因多半是初始化 better-scroll 的时机不对,或者是当 DOM 结构发送变化的时候并没有重新计算 better-scroll。

在《Vuejs高仿饿了么外卖App》课程中是这样处理的:

<template>
<div class="wrapper" ref="wrapper">
<ul class="content">
<li>...</li>
<li>...</li>
...
</ul>
</div>
</template>
<script>
import BScroll from 'better-scroll'
export default {
mounted() {
this.$nextTick(() => {
this.scroll = new Bscroll(this.$refs.wrapper, {})
})
}
}
</script>
  • Vue2.0中提供了一个获取 DOM 对象的接口—— vm.$refs,可以通过了 this.$refs.wrapper访问到了这个 DOM 对象 
  • this.$nextTick()这个方法作用是当数据被修改后使用这个方法会回调获取更新后的dom再render出来; 如果不在下面的this.$nextTick()方法里回调这个方法,数据改变后再来计算滚动轴就会出错

实现效果:

           better-scroll不能滚动的原因

需要DOM加载完成后才能正确应用. vue中应用在$nextTick中,异步初始化

子元素高度需要超过父元素。而且父元素需要设置高度(这才是better-scroll能够滚动的原理)

better-scroll在使用的时候,滚动只作用于第一个子元素,其它的元素都会被忽略。在vue中,获取的ref是ratings,它的子元素包含rating-content和rating-wrapper等多个同级元素,那么需要在这些同级元素外层,ratings内层再套一个<div>,这个<div>才是需要滚动的部分

<div class="ratings" ref="ratings">
<div> //这才是滚动的范围
<div class="rating-content"></div>
<div class="rating-wrapper"></div>
<v-split></v-split>
</div>
</div>

隐藏切换显示都会导致插件参数的scrollerHeight:0。此时需要加上click:true,使better-scroll支持点击事件,再调用下refresh()重新渲染DOM就行了

this.$nextTick(() => {
if(!this.scroll){
this.scroll = new BScroll(this.$refs.food, {
click: true
})
}else{
this.scroll.refresh();
}
}) 

最新文章

  1. aes加密C语言
  2. freemarker页面如何获取绝对路径basePath
  3. js中判断true和false的情况
  4. Unity3D重要知识点
  5. quay.io/coreos/etcd 基于Docker镜像的集群搭建
  6. hadoop 集群部署ganglia 监控服务与nagios 报警服务
  7. 【暑假】[基本数据结构]根据BFS与DFS确定树
  8. JDBC batch批处理Statement executeBatch 具体解释
  9. 从setTimeout到浏览器线程机制
  10. 【原创】纯OO:从设计到编码写一个FlappyBird (二)
  11. SharePoint 创建一个简单的Web Part 部分
  12. Python从入门到放弃之迭代器
  13. linux命令学习汇总
  14. Java final类&amp;所有构造方法均为private的类(类型说明符&amp;访问控制符)
  15. 复习下C 链表操作(双向循环链表,查找循环节点)
  16. maven 项目打可执行jar包
  17. RecyclerView--添加头部和底部
  18. JVM Troubleshooting
  19. Thinkphp5笔记五:配置data文件夹
  20. mac 连接windows 共享内容

热门文章

  1. Linux下安装php环境并且配置Nginx支持php-fpm模块[www]
  2. bootstrap,ECMA
  3. UTF-8编码中BOM的检测与删除[linux下命令]
  4. JS—正则表达式
  5. [thinkPHP] buildSql可以查看tp CURD操作对应的SQL
  6. Hash算法详解
  7. 洛谷——P3914 染色计数
  8. Jenkins上配置Robot Framework测试邮件通知模板
  9. [BZOJ 4034] 树上操作
  10. small test on 5.30 morning T3