18年年底的時候,一直在做年度報告的H5頁面,因為項目需要,需要實現上下滑動翻頁,並且上滑的頁面比正常頁面的比例要縮小一定比例。
效果類似於http://www.17sucai.com/pins/demo-show?id=7834,這個鏈接是基於jquery實現的,我寫的是和這個例子效果一樣,只不過是用vue實現的。
代碼地址:https://github.com/dreamITGirl/vuepageturn //demo
首先介紹一下,這個項目依賴的插件:上下滑動翻頁使用了v-touch,是基於hammer.js進行的vue封裝。也可以不用這個插件寫,直接用js原生,通過touchStart,touchMove,touchEnd來實現也是可以的;
現在總結一下幾點,是我在寫代碼的時候遇到的坑。
1、因為我是使用的是v-touch里的pan屬性及它附帶的方法和事件。所以,在組件內部如果還有滾動的區域,就可能會出現沖突,最后項目上線之前,仍沒有徹底解決。
不管是用v-touch還是用js原生,都會出現這個問題,在實現上下頁面滑動切換時,采用了純css去控制上下滑動的距離。所以,css可能會沖突。所以,建議不要在使用v-touch或者js原生滾動區域內部再次出現滾動區域。
下一篇博客會重點說一下這個問題的解決方式。
<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沖突。
2、滾動距離的計算
看圖理解
頁面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控制達到的樣式距離走。
