美文网首页vue
better-scroll踩坑合集

better-scroll踩坑合集

作者: ceido | 来源:发表于2019-02-22 11:07 被阅读2520次

    better-scroll
    github

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

    1.无法响应鼠标滚轮滚动:

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

            const scrollConfig = {
                click: true,
                bounce: false,
                scrollbar: true,
                preventDefault: false,
                tap: true,
                mouseWheel: true
            };
    
    2.scrollBehavior与better-scroll不兼容

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

        mounted() { // 模拟scrollBehavior
            const hash = this.$route.hash;
            setTimeout(() => { // 虽然父组件先于子组件创建,但是contentScroll是在nextTick中赋值的
                const contentScroll = this.$parent.contentScroll;
                if (contentScroll) {
                    if (hash) {
                        contentScroll.scrollToElement(hash);
                    } else {
                        contentScroll.scrollTo(0, 0);
                    }
                }
            });
        },
    
    3.点击一次多次触发

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

    引入fastclick插件。

    原理不明。

    4.position: fixed失效!

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

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

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

    5.内层有原生滚动

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

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

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

                    menu.addEventListener('wheel', (e) => {
                        e.stopPropagation();
                    });
    

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

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

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

                    menu.addEventListener('touchstart', (e) => { 
                        e.stopPropagation();
                    });
    

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

    6.滚动条位置

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

            /deep/ div.bscroll-vertical-scrollbar {
                left: 234px !important;
            }
    
    7.监听事件

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

    bscroll.on('scroll', () => {});
    
    8.容器需要固定高度

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

    解决办法:

        position: absolute;
        height: 100%;
    

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

    双层嵌套问题

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

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

    总结

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

    相关文章

      网友评论

        本文标题:better-scroll踩坑合集

        本文链接:https://www.haomeiwen.com/subject/jhdsyqtx.html