better-scroll 是一款重点解决移动端(已支持 PC)各类滚动场景需求的插件。它的核心是借鉴的 iscroll 的实现,它的 API 设计基本兼容 iscroll,在 iscroll 的基础上又扩展了一些 feature 以及作了一些性能优化。npm
better-scroll 是基于原生 JS 实现的,不依赖任何框架。它编译后的代码大小是 63kb,压缩后是 35kb,gzip 后仅有 9kb,是一款很是轻量的 JS lib。浏览器
先来看一下浏览器的滚动原理:浏览器的滚动条你们都会遇到,当页面内容的高度超过视口高度的时候,会出现纵向滚动条;当页面内容的宽度超过视口宽度的时候,会出现横向滚动条。也就是当咱们的视口展现不下内容的时候,会经过滚动条的方式让用户滚动屏幕看到剩余的内容。性能优化
better-scroll 也是同样的原理,以下图,能够更直观的来感觉一下:bash
绿色部分为 wrapper,也就是父容器,它会有固定的高度。黄色部分为 content,它是父容器的第一个子元素,它的高度会随着内容的大小而撑高。那么,当 content 的高度不超过父容器的高度,是不能滚动的,而它一旦超过了父容器的高度,咱们就能够滚动内容区了,这就是 better-scroll 的滚动原理。app
注:在使用的时候外部容器的须要设置固定高度,还有一个问题须要设置overflow:hidden
,这是由于为了隐藏超出部分。
有一点须要特别注意:滚动的元素只能是第一个容器的第一个元素框架
例如:dom
经过npm引入ide
安装better-scroll函数
npm install better-scroll
oop
引入better-scroll
import BScroll from 'better-scroll'
若是不支持import
,请使用require
来引入
开始使用插件
DOM结构
<div class="wrapper">
<ul class="content">
<li>...</li>
<li>...</li>
...
</ul>
</div>
复制代码
wrapper里只能有一层元素,也就是须要滚动的元素,使用了better-scroll以后,会自动在content加上动画的样式。
<!-- 这种结构是不能够滚动的 -->
<div class="wrapper">
<ul class="content">
...
</ul>
<ul class="content">
...
</ul>
</div>
<!-- 若是须要滚动的话加一层div包裹着两个ul标签 -->
复制代码
wrapper必定须要指定高度,否则是没法滚动的。 须要看系统使用的定位是absolute仍是flex,若是是flex是有默认的高度的,就不须要本身手动设置wrapper的高度。
注:父级bscroll必须有高度,而且overflow为hidden;
插件使用
mounted(){
this.$nextTick(() => {
let bscrollDom = this.$refs.bscroll;
this.bscroll = new BScroll(bscrollDom,{ Option参数 }) //重点代码
})
}
复制代码
注:
1.插件初始化时须要具体元素,因此在DOM
结构中使用ref
标记元素(而后使用上面的代码$refs
获取元素),以备插件使用;
2.建议放在nextTick
方法里面,避免DOM
结构未渲染完成,从而形成子元素bscroll-container
高度计算不许确;
3.建议使用this.bscroll
方式定义,以备在其余方法中使用;
4.使用时必定要 new,使用时必定要 new,使用时必定要 new
重要的事情说三遍
例如:
let scroll = new BScroll(document.getElementById('wrapper'),{
probeType: 3
})
scroll.on('scroll', (pos) => {
console.log(pos.x + '~' + pos.y)
...
})
复制代码
Events 列表
滚动到某个位置,x,y 表明坐标,time 表示动画时间,easing 表示缓动函数
例如:
let scroll = new BScroll(document.getElementById('wrapper'))
scroll.scrollTo(0, 500)
...
复制代码
滚动到某个元素,el(必填)表示 dom 元素,time 表示动画时间,offsetX 和 offsetY 表示坐标偏移量,easing 表示缓动函数
强制 scroll 从新计算,当 better-scroll 中的元素发生变化的时候调用此方法。
当 snap 为 true 时,获取滚动的当前页,返回的对象结构为 {x, y, pageX, pageY},其中 x,y 表明滚动横向和纵向的位置;pageX,pageY 表示横向和纵向的页面索引
当 snap 为 true,滚动到对应的页面,x 表示横向页面索引,y 表示纵向页面索引, time 表示动画,easing 表示缓动函数
启用 better-scroll,默认开启
禁用 better-scroll
销毁 better-scroll,解绑事件
当 DOM 结构发生变化的时候务必要调用refresh()确保滚动的效果正常,从新渲染高度
还有就是我上面写的DOM层级关系,wrapper里面必定不能存在多个同级的标签
如下面dom结构为例:
<div class="classifyTitle" ref="wrapper">
<ul>
<li v-for="(item,index) in classifyData.products">
<router-link :to="{name:'详情'}">{{item.title}}</router-link>
</li>
</ul>
</div>
复制代码
审查元素能够看到:
这样即添加成功的
只有content的高度大于wrapper高度时候,才能够滚动。
如何看?
this.$nextTick(() => {
if (!this.scroll) {
this.scroll = new BScroll(this.$refs.wrapper, {})
console.log(this.scroll)
}
})
复制代码
F12就能够看到打印结果:
以上就是能够滚动的状况,wrapperHeight(616) < scrollHeight(750),hasVerticalScroll为true;
若是这些数据不对,检查是否dom没有更新完就初始化BScroll了,要等dom更新完才能初始化
.wrapper元素上要给定位
position: absolute;
left: 0;
top: 0;
overflow: hidden;
复制代码