使用better-scroll解决ios滚动问题

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了使用better-scroll解决ios滚动问题相关的知识,希望对你有一定的参考价值。

参考技术A 最近在项目开发中,遇到一个令人头疼的问题。当一个容器能左右滑动时,手指在该容器上做上下滑动的手势页面不会上下滚动(在容器外围上下滑动是可以的,所以排除页面的scroll问题),并且这个问题只会在ios上出现,安卓没有。

通过查资料发现,原生的IOS scroll有这个问题,所以就使用了本文所讲的better-srcoll来解决。下面来讲讲如何使用better-scroll来实现左右和上下滚动。

2.引入better-scroll

使用BScroll实例化之前必需要等待DOM渲染完成。
产生左右滚动的条件是子盒子内的宽度必须要大于父盒子的宽度,所以我们在用better-scroll时,必须要先得到滚动区域的尺寸和父盒子的尺寸,来计算出是否能滚动。
下面是一个小demo

(1)class为content的div的父盒子,在此区域内滚动,需要通过ref拿到DOM。
(2)ul元素是子盒子,包含若干个li元素,可以通过li元素的宽度动态进行计算,也可以通过ref获取dom

给li标签90px的宽度,确保子盒的宽度大于父盒子的宽度
3.使用better-scroll

(1) 首先拿到所有的li元素的宽度,赋值给ul元素
(2) 生成BScroll实例,其中this.$refs.content就是父盒子的DOM,在此区域内滚动。

需要给父元素一个固定的高度,并且overflow属性为hidden

4.效果图

使用better-scroll后可能会出现点击事件发生两次的情况,这时只需要在配置参数

click改为false就可以了。
想要了解更多参数及其使用方法请前往: better-scroll文档地址

better-scroll踩坑合集

参考技术A better-scroll
github

最近项目使用了better-scroll这个插件,这个插件用起来还是有不少问题的。
除了普遍会遇到的无法滚动、无法点击等问题,这些作者都已经说得很清楚了。下面说说我遇到的其他问题及解决方法。

无法点击大家都知道了,在创建bscroll时传入配置即可。但是在PC端时,你会发现滚轮无法使内容滚动,而且文档也没有相关说明!看了源码后,发现配置一个 mouseWheel 选项即可解决:

vue的 scrollBehavior 可以用于配置路由,比如说滚动到锚点。但是如果你的锚点是在bscroll容器中, scrollBehavior 就失效了。解决:

当设置 click: true ,点击bscroll容器的元素时,会触发两次甚至多次click事件。这个问题在iscroll中也存在。解决办法:

引入fastclick插件。

原理不明。

bscroll的滚动是用 transform 的 translate 来进行偏移,但是父元素设置了transform,所有子元素的position: fixed都不再相对于视口,而是相对于这个transform父元素!这不是什么bug,而是规范中规定。一直以为fixed定位霸道至极,没想到transform可以改变它的定位,学到了。
参考

这样的话,bscroll容器内的fixed定位元素就全乱套了。
Google了一番,除了把fixed元素放出来,没有什么好办法。有的人也说了:如果一个元素是fixed定位,它就不应该被其他元素包裹,直接放到根元素下。

但是,你要知道,如果是使用第三方的组件库,比如element、antdesign,我想改也改不了啊!

内层有原生滚动会引起两个问题:

(1) PC端当鼠标移动到原生滚动元素上,滚动滚轮,内层原生滚动无响应!倒是bscroll容器发生了滚动,就好像内层这个滚动完全不存在。

解决办法,阻止内层滚动的冒泡:

同样的,如果元素是第三方的组件,改起来很烦。

(2)移动端,引起外层抖动!

同样是因为事件冒泡到外层,导致里面滚,外面也滚。体验极差。解决办法:

同样的,如果元素是第三方的组件,改起来很烦。

我有两个并列的scroll,一左一右。但是左边scroll的滚动条竟然去到了浏览器右边,查看了一下属性为right: 0。解决办法,覆盖样式:

如何监听事件文档中也没有说:

容器需要固定高度,这本来也没什么。如果高度是百分比,以适应容器父元素的高度变化。但是如果父元素也没有高度呢?大家都知道,父元素没高度时,子元素 height: 100% 是无效的。我父元素要flex: 1自适应,这也是没有高度的,父元素设置 height: 100% 也是无效的。那么如何让父元素有高度又能自适应呢?

解决办法:

下面是我查问题时在issue看到的一些问题,记录下来。(顺便吐槽一下,issue也太乱了吧,完全把issue当贴吧了!GitHub几时能出个删issue的功能啊!)

双层嵌套使用了stopPropagation: true,但是里面的滚动如果滚到底或者滚到顶部,触发不了最外层的滚动。
解决办法:内层滚动到底或者滚到顶部时,内层调用disable进行禁止,然后外层调用enable启用。

最后,如果你不开启 preventDefault: false ,许多原生的效果都会失效。transform滚动也注定了原生滚动的失效。

使用心得:PC端没必要引入!当初是考虑到项目要兼容移动端才引入的。但没想到带来那么多问题。如果移动端要做回弹动画、下拉刷新、无限滚动效果,是可以考虑使用的。如果要引入,可以做一下兼容:在移动端时使用这个插件,而在PC端时,调用destory方法销毁bscroll,使用原生。

以上是关于使用better-scroll解决ios滚动问题的主要内容,如果未能解决你的问题,请参考以下文章

VUE 滚动插件(better-scroll)

js原生滚动与使用插件better-scroll不起作用原因

better-scroll中嵌套原生滚动组件,原生滚动组件失效问题

better-scroll插件的实战

better-scroll使用参考

better-scroll踩坑合集