之前为了让移动端滚动条滚动的更加顺滑,经常利用iscroll框架,来适配移动端的滚动,但是目前iscroll框架作者已经不维护了,之后国内一位程序员根据iscroll的源码,写了一个支持更多特性,滚动性能更高的better-scroll框架
优点:
API基本兼容iscroll,在iscroll的基础上扩展了一些特性以及做了一些性能优化基于原生JS实现,不依赖任何框架体积小,编译后代码只有63kb,压缩后是35kb,gzip后仅有9kb,非常轻量2.问题描述:
当我们的内容超过浏览器的整个窗口,就会出现滚动,内部利用的原理就是利用浏览器默认可滚动的属性,超出浏览器窗口即滚动
注意:利用这种原理实现的滚动,在移动端是非常卡顿的
3.解决方案:
BetterScroll的引入及使用
代码一如下:
<template>
<div class="wrapper">
<ul class="content">
<li>分类列表1</li>
<li>分类列表2</li>
<li>分类列表3</li>
<li>分类列表4</li>
<li>分类列表5</li>
<li>分类列表6</li>
<li>分类列表7</li>
<li>分类列表8</li>
<li>分类列表9</li>
<li>分类列表10</li>
<li>分类列表11</li>
<li>分类列表12</li>
<li>分类列表13</li>
<li>分类列表14</li>
<li>分类列表15</li>
<li>分类列表16</li>
<li>分类列表17</li>
<li>分类列表18</li>
<li>分类列表19</li>
<li>分类列表20</li>
</ul>
</div>
</template>
<script>
import BScroll from 'better-scroll'
export default {
name: "Category",
data() {
return {
scroll: null
}
},
created() {
this.scroll = new BScroll('.content', {
})
},
}
</script>
<style scoped>
.content {
height: 150px;
background-color: red;
/* overflow: hidden; */
/* overflow-y: scroll; */
}
</style>
3.1 问题一
3.1.1 问题解决思路引入后发现滚动并没有生效,如下图一所示:
原因分析一:
1.先看一下BetterScroll的滚动原理:BetterScroll 的原理与浏览器相同。我们可以通过一张图片更明显地感受到这一点:绿色部分是包装器,也称为父容器,具有固定的高度。黄色部分是内容,它是父容器的第一个子元素,其高度会随着内容的大小而增长。然后,当内容的高度不超过父容器的高度时,内容不会滚动。一旦超过,内容可以滚动。这就是 BetterScroll 的原理。
2.明白了BetterScroll的原理,我们得知滚动需要在最外层的包装器加滚动,所以需要在created()的生命周期做更改
解决思路: 将代码一中的 this.scroll = new BScroll(‘.content’, {})换成this.scroll = new BScroll(‘.wrapper’, {})
但是上述改动发现滚动如图一所示依然不生效
原因分析二:
1.最外层包裹的wrapper可能在很多地方都用到了这个类名,导致拿不到这个dom结构
解决思路: 用ref标记,再通过$refs来获取dom元素,这样就可以避免类名多次用到而获取不到dom的问题
绝望的是改动后依然如图一一样不生效。控制台报如下错误:
原因分析三: 想了好久,依然找不到问题,因为原因二中的报错就是找不到dom元素的问题,最后看了一下官方文档中的生命周期,发现了问题所在。因为在created()中dom结构还未经编译,此时 *** 作dom,均不生效,而在mounted()中, *** 作dom才有效,真是豁然开朗啊。最后针对官方文档中vue的生命周期图的每一步做了一下深层次分析,标记在了图的旁边。
最后生效后的代码如下:
代码二如下:
生效后如图二所示:
4.功能优化: 4.1 优化一
在我们滑动滚动条时,有时需要一个快捷的按钮,可以直接回到顶部,避免了图片较多时,用户需要不断的滑动滚动条才能回到顶部,增加了用户的体验,所以需要在首页增加一个滑动到某位置时回到顶部的按钮,此处也需要用到better-scroll框架
注意:修饰符.native什么时候可以使用?
在我们需要监听一个组件的原生事件时,必须给对应的事件加上.native修饰符,才能进行监听
mounted() {
this.scroll = new BScroll(this.$refs.wrapper, {
})
},
methods: {
scrollTo(x, y, time=300) {
this.scroll.scrollTo(x, y, time)
}
},
封装back-top组件
<div class="home">
<nav-bar class="home-nav"><div slot="center">购物街</div></nav-bar>
<scroll class="content" ref="scroll">
<home-swiper :banners="banners"></home-swiper>
<recommend-view :recommends="recommends"></recommend-view>
<feature-view></feature-view>
<tab-control class="tab-control" :titles="['流行','新款','精选']" @tabClick='tabClick'></tab-control>
<goods-list :goods="showGoods"></goods-list>
</scroll>
<back-top @click.native="backClick"></back-top>
</div>
methods: {
backClick(){
this.$refs.scroll.scrollTo(0, 0)
},
优化一效果如下图:
4.2 优化二上述优化还有一个小改进就是,当我们上划到某个位置时,再显示回到顶部的按钮,而不是让他一直显示,这里应该对他进行控制显示和隐藏,实时监听滚动的位置。
Home.vue文件:
<div class="home">
<nav-bar class="home-nav"><div slot="center">购物街</div></nav-bar>
<scroll class="content" ref="scroll" :probeType="3" @scroll="contentScroll">
<home-swiper :banners="banners"></home-swiper>
<recommend-view :recommends="recommends"></recommend-view>
<feature-view></feature-view>
<tab-control class="tab-control" :titles="['流行','新款','精选']" @tabClick='tabClick'></tab-control>
<goods-list :goods="showGoods"></goods-list>
</scroll>
<back-top @click.native="backClick" v-show="isShowBackTop"></back-top>
</div>
methods: {
backClick(){
this.$refs.scroll.scrollTo(0, 0)
},
contentScroll(position) {
this.isShowBackTop = (-position.y) > 1000
},
}
Scroll.vue文件:
mounted() {
// 1.创建BScroll对象
this.scroll = new BScroll(this.$refs.wrapper, {
click: true,
probeType: this.probeType
})
// 2.监听滚动的位置
this.scroll.on('scroll', (position) => {
this.$emit('scroll',position)
})
},
优化二效果如下图:
5.滚动区域的bug分析和解决: 5.1 问题原因分析:
我们将滚动的区域封装成了scroll.vue组件,scroll.vue它在决定里面有多少区域可以滚动时,它是根据内容决定的。better-scroll在计算内容高度的时候,由于内容里面有很多图片,这些图片还没有被加载出来,但是高度已经被计算出来,当图片被加载完成后,高度很明显比之前的高度要高,但是better-scroll并不知道有一个新的高度,导致无法滚动(可滚动区域高度见5.3问题解决截图)。
5.2 bug重现效果图:5.3 问题解决:我们在滚动时,时不时会出现下面的情况,即滚动出现卡顿无法滚动的情况,稍等片刻,即可以滚动,体验起来比较差
5.3.1 可滚动区域异常和正常时的高度:
5.3.2 解决思路:
监听每一张图片是否加载完成,只要有一张图片加载完成了,执行一次refresh()
原生的js监听图片:img.onLoad = function(){}vue中监听:@load=‘方法’调用scroll的refresh()如何监听图片加载完成了?
5.3.3 效果图:
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)