18年年末的時候,一直在作年度報告的H5頁面,由於項目須要,須要實現上下滑動翻頁,而且上滑的頁面比正常頁面的比例要縮小必定比例。css
效果相似於http://www.17sucai.com/pins/demo-show?id=7834,這個連接是基於jquery實現的,我寫的是和這個例子效果同樣,只不過是用vue實現的。vue
代碼地址:https://github.com/dreamITGirl/vuepageturn //demojquery
首先介紹一下,這個項目依賴的插件:上下滑動翻頁使用了v-touch,是基於hammer.js進行的vue封裝。也能夠不用這個插件寫,直接用js原生,經過touchStart,touchMove,touchEnd來實現也是能夠的;git
如今總結一下幾點,是我在寫代碼的時候遇到的坑。github
一、由於我是使用的是v-touch裏的pan屬性及它附帶的方法和事件。因此,在組件內部若是還有滾動的區域,就可能會出現衝突,最後項目上線以前,仍沒有完全解決。數組
無論是用v-touch仍是用js原生,都會出現這個問題,在實現上下頁面滑動切換時,採用了純css去控制上下滑動的距離。因此,css可能會衝突。因此,建議不要在使用v-touch或者js原生滾動區域內部再次出現滾動區域。spa
下一篇博客會重點說一下這個問題的解決方式。插件
<v-touch class="container" @panstart.prevent="panStart" @panmove.prevent="panMove" @panend.prevent="panEnd"> <component v-for="(val,index) in componentList" :key="index" :is="val" :style="{ zIndex:zIndex(index), transition:`all ${transition(index)}s`, transform:`translateY(${top(index)}) scale3d(${scale(index)},1,${scale(index)})` }" ></component> </v-touch>
若是在component中仍有滑動的區域的話,就會產生css衝突。3d
二、滾動距離的計算code
看圖理解
頁面1,頁面2,頁面3分別對應我要上下滑動切換的頁面,而且,1,2,3分別對應組件中的三個組件,也就是說,每一個頁面都是一個獨立的組件。而這些組件是經過v-for的方式循環渲染的。
須要控制的是每一個頁面的top值,z-index值,scale值,以及爲了實現平滑的效果transition的過渡時間。
當頁面向上(下)滑動時,頁面3(頁面1)就變成了當前展現的頁面,頁面2就變成了前一個頁面(下一個頁面),由於頁面3(頁面1)是最後(第)一個頁面了,用戶不能再繼續向下滑,
因此,咱們須要在panmove和panend時去依據當前的index值和當前展現的組件數組中最後一項和第一項去判斷
重點說一下在panmove的時候,也就是在滾動過程當中的時候,頁面的變化以及top值和滑動的距離是如何計算的。仍是看圖:
這個裏面最難理解的就是這個上滑,或者下滑的距離,在個人代碼裏,1.0版本的並無解決兩個頁面始終差一段距離,這個距離就是distance的2/3,在panend的時候,咱們須要看一下用戶滑動的距離是否是能夠翻頁,若是距離很小,則不能翻頁,最好加一下判斷。
上滑以後,頁面1就變成了其餘頁面,頁面2變成了前一個頁面,頁面3變成了當前頁面,對這3個頁面來講,它們各向上走了一個屏幕的高度,而頁面3的高度top值變成了0,頁面2變成了-1*屏幕的高度。頁面1則變成了-2 * 屏幕的高度,可是對於頁面1來講,已經變成了其餘的圖片,因此它的高度,是(它的index-當前的index)*屏幕的高度。
對於當前上滑(下滑)的頁面縮放的解決,是在panstart的時候,設置當前頁面的縮放率爲1,在panmove的時候根據滑動的距離,隨機設置縮放率。在panend的時候,設置延遲,使縮放率變成。
因此,正常的滑動過程當中的樣式是
具體的代碼,你們能夠去github上自行下載使用,若是不使用v-touch,也能夠用touchStart,touchMove,touchEnd分別對應顯示。
更新:1.1版本中刪掉了component循環渲染時的top屬性,這樣,在上滑下滑的時候,就不會出現中間的距離差,只會按照js控制達到的樣式距離走。