最近項目使用了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的滾動是用transform
的translate
來進行偏移,但是父元素設置了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端時,調用destory方法銷毀bscroll,使用原生。
轉載鏈接:https://www.jianshu.com/p/6338a8033281