天天看點

移動端開發HTML5(H5)采用SwiperJS單屏垂直滑動頁面中,某頁内容高度超出螢幕高度解決辦法...移動端開發HTML5(H5)采用SwiperJS單屏垂直滑動頁面中,某頁内容高度超出螢幕高度解決辦法

移動端開發HTML5(H5)采用SwiperJS單屏垂直滑動頁面中,某頁内容高度超出螢幕高度解決辦法

當産品給我原型的時候,我覺得這是一個普通的專題,為了趕時間(下班前給的設計稿,産品姐姐說,明早要上!)。當我下班時拿到設計師給出了基于iPhone6分辨率的設計稿時,我陷入了沉思。

不得不說,整體設計十分飽滿,看起來内容很豐富。在750*1334分辨率下的圖檔顯示完美。

然而,不是所有手機看到的都是這個圖的模樣,最重要的是不同浏覽器有不同高度的标題欄,底部有菜單欄,還有甚者,還有虛拟按鍵欄(某些安卓手機例如Meizu MX3)。作為單屏垂直滑動的頁面,如果能完美呈現如此飽滿的内容,并且不會出BUG呢。

廢話少說,目前的狀況就是:這個單屏滑動的頁面中,存在部分slide的内容根本無法一屏剛好顯示完,是以,在這些高度大于浏覽器可視窗高度的slide内,需要一個上下滑動來檢視該slide全部内容。而兩個上下滑動的操作又會産生沖突。對于這個問題該如何解決呢?經過這幾天的研究,我目前得出來了兩個方案。現在來介紹一下:

方案一:在超出可視高度的swiper-slide的内通過設定

allowTouchMove

參數來開啟/禁用滑屏切換的操作

該方案内容較長,廢話較多,是個人嘗試解決問題的一點心得,若無興趣可直接看方案二

開發流程和思考:

首先建議下載下傳demo-1在本地,通過Chrome手機模拟或者手機(手機預覽需要自行開本地伺服器)運作一下看看效果,體驗一下實際使用感受和覺得有哪些問題。

由于整個頁面僅花了幾個小時完成,大部分時間用于閱讀swiperjs官方文檔解決該問題,是以頁面代碼相對混亂,并且方案一并非最優化方案,是以不再優化。其實也因為對于swiperjs的API不夠熟悉,是以寫了很多不太優化的備援代碼,是以DEMO-1主要介紹我的一些開發過程中勉強實作效果的想法。

前奏:

坑爹的設計啊,又不是人人都是iPhone6!T_T。設計稿單屏顯示效果好,時間不夠設計是不可能改了,找産品聊天,說,既然都單屏滑動,這個設計内容太飽和,我壓縮一下,盡量大部分裝置能顯示完整内容區域,産品不同意。可是苦了我這個小前端。口頭上對産品說,那你找個内容超出螢幕高度的執行個體我看看,我都沒見過!心裡還是軟軟的,要不試試吧,說不定很容易呢。

開發ing:

先按照SwiperJs的DEMO搭好頁面,做好樣式。反正趕時間,全部切整圖,細節不管了。很快頁面雛形有了。此刻沒有開始的loading的。

接下來做滑動,很顯然,的确按照設計稿一屏根本顯示不完,加上該死的各種狀态欄占用的高度,實際可視區域很小。然而怎麼擷取到每屏内部的高度呢,有些屏是整張背景圖,是沒有高度的,這種,好說,我直接寫高寬最小100%。有的有内容,但是如何檢測到呢,首先每個slide裡面都要有一個wrap,我這裡用的類名page,所有樣式都是基于page來的,然後頁面加載的時候,在底部建立了個臨時的div,周遊有幾個slide,每次都将slide寫入臨時div,然後擷取到真實高度,再添加一個realheight屬性給對應的slide,周遊結束後清除臨時div,這樣每個slide的真實高度就有了。

接下來,每次滑倒對應的slide的時候,開始檢測它的内容高度realheight,是否超出了可視區高度,如果超出,我就阻止了

allowTouchMove

,如下:

mySwiper.allowTouchMove = false;
           

這下可以内部滾動了,但是到了底我要滑到下一屏咋辦,要釋放allowTouchMove,于是又在這裡加了一個滾動監聽事件,當滾到底部時,設定為true,當然同樣到滑倒頂部也要設定true,以便傳回上一屏,止于此處的具體優化就不多說了。原理大概就是這樣~

似乎都調試好了,其實還有個隐藏的問題,就是我這個頁面的圖檔較多,網速較差的情況下,圖檔未能加載完,真實高度是無法擷取到的。于是又要想辦法弄了一個圖檔加載結束後才開始執行其他腳本。這裡趕時間也就随便找了一段抄過來了,還挺好用。抄自Can I sync up multiple image onload calls?,順便又加了個簡單的loading頁面。反複測試了幾次,看起來勉強還是可以的,于是找産品聊了聊,好在基本上過了。

總結:

雖說,其實代碼方面有很多問題,但是有時候工作上速度比品質更重要,也就先這樣上線了~同樣的我在上線後有了時間的情況下,繼續尋求更佳的解決辦法,于是才找到方案二~

方案二:作者給出的完美方案(4.x測試通過 )

通過監聽swiperjs内部的

touchstart

touchmove

擷取到手指滑動的垂直高度差,判斷滑動手勢的方向,并擷取

slide.scrollHeight

slide.offsetHeight

值(也就是DEMO-1中的擷取頁面可視區域高度的方法。),以便得到正确的是否為内部滾動檢測。如果是,則阻止

touchmove

事件,我當時完全不知道這個阻止了就能阻止切屏了。

當然,css對應的也要寫好。

.swiper-container {
  width: 100%;
  height: 100%;
}

.swiper-slide {
  background: #f1f1f1;
  color: #000;
  text-align: center;
  overflow: auto;
  -webkit-overflow-scrolling: touch;
}
           

其實看一下源碼就很清楚了。在目前,我未發現任何BUG。也算是完美了SwiperJS的另一個官方未有展示的功能~

最後附上demo-2代碼和頁面線上效果

寫在最後

其實,有時候,自己遇到的問題,其實很多人都遇到過,雖然在處理這個問題上,百度的确搜不到相關的資訊,甚至是這樣的問題,我都不知道該如何描述清楚,以便搜尋,所幸google了一下swiper slide content overflow之類關鍵詞查到了SwiperJS作者給出的答案,實在幸運,後來該頁面在優化過程中我重寫用了DEMO-2的方案,心情也是舒暢了許多。

同時,我也查過SF,關于SwiperJS的一些類似的資料,的确也沒有找到,不知道我寫的這個是否能給相關開發的朋友帶來幫助,或者其實大家還有更好的方法,歡迎留言共同學習探讨~

繼續閱讀