-
介紹better-scroll
better-scroll 最常見的應用場景是列表滾動,我們來看一下它的 html 結構
<div class="wrapper">
<ul class="content">
<li>...</li>
<li>...</li>
...
</ul>
<!-- 這裏可以放一些其它的 DOM,但不會影響滾動 -->
</div>
上面的代碼中 better-scroll 是作用在外層 wrapper 容器上的,滾動的部分是 content 元素。這裏要注意的是,better-scroll 只處理容器(wrapper)的第一個子元素(content)的滾動,其它的元素都會被忽略。
最簡單的初始化代碼如下:
import BScroll from 'better-scroll'
let wrapper = document.querySelector('.wrapper')
let scroll = new BScroll(wrapper)
-
better-scroll在vue中的使用
安裝 npm install better-scroll --save
<template>
<div class="wrapper" ref="wrapper">
<ul class="content">
<li>...</li>
<li>...</li>
...
</ul>
</div>
</template>
<script>
import BScroll from 'better-scroll'
export default {
mounted() {
this.$nextTick(() => {
this.scroll = new Bscroll(this.$refs.wrapper, {})
})
}
}
</script>
Vue.js 提供了我們一個獲取 DOM 對象的接口—— vm.$refs
。在這裏,我們通過了 this.$refs.wrapper
訪問到了這個 DOM 對象,並且我們在 mounted 這個鉤子函數裏,this.$nextTick 的回調函數中初始化 better-scroll 。因爲這個時候,wrapper 的 DOM 已經渲染了,我們可以正確計算它以及它內層 content 的高度,以確保滾動正常。
這裏的 this.$nextTick
是一個異步函數,爲了確保 DOM 已經渲染,感興趣的同學可以瞭解一下它的內部實現細節,底層用到了 MutationObserver 或者是 setTimeout(fn, 0)。其實我們在這裏把 this.$nextTick 替換成 setTimeout(fn, 20) 也是可以的(20 ms 是一個經驗值,每一個 Tick 約爲 17 ms),對用戶體驗而言都是無感知的。
-
better-scroll的事件
<template>
<div class="wrapper" ref="wrapper">
<ul class="content">
<li v-for="item in data">{{item}}</li>
</ul>
<div class="loading-wrapper"></div>
</div>
</template>
<script>
import BScroll from 'better-scroll'
export default {
data() {
return {
data: []
}
},
created() {
this.loadData()
},
methods: {
loadData() {
requestData().then((res) => {
this.data = res.data.concat(this.data)
this.$nextTick(() => {
if (!this.scroll) {
this.scroll = new Bscroll(this.$refs.wrapper, {})
this.scroll.on('touchend', (pos) => {
// 下拉動作
if (pos.y > 50) {
this.loadData()
}
})
} else {
this.scroll.refresh()
}
})
})
}
}
}
</script>
這段代碼比之前稍微複雜一些, 當我們在滑動列表鬆開手指時候, better-scroll 會對外派發一個 touchend 事件,我們監聽了這個事件,並且判斷了 pos.y > 50(我們把這個行爲定義成一次下拉的動作)。如果是下拉的話我們會重新請求數據,並且把新的數據和之前的 data 做一次 concat,也就更新了列表的數據,那麼數據的改變就會映射到 DOM 的變化。需要注意的一點,這裏我們對 this.scroll 做了判斷,如果沒有初始化過我們會通過 new BScroll 初始化,並且綁定一些事件,否則我們會調用 this.scroll.refresh 方法重新計算,來確保滾動效果的正常。
官網https://ustbhuangyi.github.io/better-scroll/doc/zh-hans/#better-scroll%20%E6%98%AF%E4%BB%80%E4%B9%88
參考https://zhuanlan.zhihu.com/p/27407024