better-scroll的原理
1.什么是 better-scroll?
better-scroll 是一個移動端滾動的解決方案,它不僅可以做普通的滾動列表,還可以做輪播圖、picker 等等。
2.better-scroll的滾動原理?
先來看一下瀏覽器的滾動原理,瀏覽器的滾動條大家都會遇到,當頁面內容的高度超過視口高度的時候,會出現縱向滾動條;當頁面內容的寬度超過視口寬度的時候,會出現橫向滾動條。也就是當我們的視口展示不下內容的時候,會通過滾動條的方式讓用戶滾動屏幕看到剩余的內容。那么對於 better-scroll 也是一樣的道理,我們先來看一下 better-scroll 常見的 html 結構:
為了更加直觀,我們再來看一張圖:
綠色部分為 wrapper,也就是父容器,它會有固定的高度。黃色部分為 content,它是父容器的第一個子元素,它的高度會隨着內容的大小而撐高。那么,當 content 的高度不超過父容器的高度,是不能滾動的,而它一旦超過了父容器的高度,我們就可以滾動內容區了,這就是 better-scroll 的滾動原理。
那么,我們怎么初始化 better-scroll 呢,如果是上述 html 結構,那么初始化代碼如下:
import BScroll from 'better-scroll' let wrapper = document.querySelector('.wrapper') let scroll = new BScroll(wrapper, {})
better-scroll 對外暴露了一個 BScroll 的類,我們初始化只需要 new 一個類的實例即可。第一個參數就是我們 wrapper 的 DOM 對象,第二個是一些配置參數,具體參考 better-scroll 的文檔。
better-scroll 的初始化時機很重要,因為它在初始化的時候,會計算父元素和子元素的高度和寬度,來決定是否可以縱向和橫向滾動。因此,我們在初始化它的時候,必須確保父元素和子元素的內容已經正確渲染了。如果子元素或者父元素 DOM 結構發生改變的時候,必須重新調用 scroll.refresh()
方法重新計算來確保滾動效果的正常。所以同學們反饋的 better-scroll 不能滾動的原因多半是初始化 better-scroll 的時機不對,或者是當 DOM 結構發送變化的時候並沒有重新計算 better-scroll。
如何在 Vue 中使用 better-scroll
Vue.js 提供了我們一個獲取 DOM 對象的接口—— vm.$refs
。在這里,我們通過了 this.$refs.wrapper
訪問到了這個 DOM 對象,並且我們在 mounted 這個鈎子函數里,this.$nextTick
的回調函數中初始化 better-scroll 。因為這個時候,wrapper 的 DOM 已經渲染了,我們可以正確計算它以及它內層 content 的高度,以確保滾動正常。
異步數據的處理
在我們的實際工作中,列表的數據往往都是異步獲取的,因此我們初始化 better-scroll 的時機需要在數據獲取后,代碼如下:
---------------------------------------------------------------------------------------------------
之前在做去哪兒網項目中better-scroll失效的原因過程如下:
可以很清晰的看到,上述代碼中並沒有父級盒子,於是我加了個父級盒子,也給父級盒子給了一個固定的高度,然后就能正常滾動起來了,具體的實現過程如下: