better-scroll踩坑合集

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了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的踩坑合集及搜罗的解决办法

 

x1
>
<
>>
<<
O

better-scroll 是一款重点解决移动端(已支持 PC)各种滚动场景需求的插件。它的核心是借鉴的 iscroll 的实现。better-scroll 基于原生 JS 实现的,不依赖任何框架,所以使用起来也十分的方便。

注意点:

  1. 使用时better-scroll是作用在外层的wrapper容器上的,滚动的部分是content---需要注意的是,better-scroll只处理容器的第一个子元素,其他的元素会被忽略,如果里面需要滚动的部分有好几部分。一定要拿一个元素把他包裹起来
  2. 还有就是better-scroll初始化了,但是没法滚动。大家知道浏览器滚动的原理是页面的高度超过视口高度的时候,才会出现滚动条。也就是说父容器一定要有一个固定的高度并且溢出隐藏,子容器的高度要大于父元素的高度,才能滚动
  3. 滚动的原理
    1 element.style {
    2     transition-duration: 0ms;
    3     transform: translate(0px, 0px) scale(1) translateZ(0px);
    4     transition-timing-function: cubic-bezier(0.165, 0.84, 0.44, 1);
    5 }

    通过滑动的距离动态改变translate的值来实现,让它相对于父级移动,就有了一种滚动的效果,但是这里就又有了下一个坑

  4. 滚动元素里面的某一块元素的position:fixed失效,本来我们想实现一个效果是滚动到某一高度让它有个吸顶效果,但是它死活吸不上去,实验了几次后发现它的fixed是相对于它的父容器定位的---

    fixed定位的元素,如果父级有transform样式,值不为none,那么fixed定位就会失效,scale(),rotate()都会使fixed定位失效。

    解决方法:使用transform样式的元素,不要包含fixed定位的子元素;css3的新属性:flex;很好的解决了在transform下fixed失效的问题;也可以添加类和移除类

  5. 使用下拉加载的时候,一定不能把包裹子元素的容器重新渲染,这样滚动事件就会失效,因为你第一次初始化时给这个容器写上样式了,如果重新渲染的时候这些样式就会被覆盖,没有样式就不会滚动了,除非你再初始化一下这个容器,但是太麻烦不建议这样使用
  6. 当 DOM 结构发生变化的时候务必要调用refresh()确保滚动的效果正常,重新渲染高度
 

以上是关于better-scroll踩坑合集的主要内容,如果未能解决你的问题,请参考以下文章

Python使用pyinstaller打包踩坑合集

Python使用pyinstaller打包踩坑合集

Python使用pyinstaller打包踩坑合集

移动端踩坑合集

react-native踩坑合集,来源于真实企业开发(建议收藏)

react-native踩坑合集,来源于真实企业开发(建议收藏)