移動端web頁面文字框+fixed
還是保留之前的態度,依然不推薦在 Android下使用 iScroll。在開發專案時,可以考慮分為兩個版本:iOS下使用 iScroll的解決方案,Android下使用 position:fixed。
移動端業務開發,iOS 下經常會有 fixed 元素和輸入框(input 元素)同時存在的情況。 但是 fixed 元素在有軟鍵盤喚起的情況下,會出現許多莫名其妙的問題。 這篇文章裡就提供一個簡單的有輸入框情況下的 fixed 佈局方案。
iOS下的 Fixed + Input BUG現象
讓我們先舉個栗子,最直觀的說明一下這個 BUG 的現象。 常規的 fixed 佈局,可能使用如下佈局(以下僅示意程式碼):
|
對應的樣式如下:
|
然後看起來就是下面這個樣子。拖動頁面時 header 和 footer 已經定位在了對應的位置,目測沒問題了。
fixed定位
但接下來問題就來了!如果底部輸入框軟鍵盤被喚起以後,再次滑動頁面,就會看到如下圖所示:
我們看到 fixed 定位好的元素跟隨頁面滾動了起來… fixed 屬性失效了!
這是為什麼呢?簡單解釋下: > 軟鍵盤喚起後,頁面的 fixed 元素將失效(即無法浮動,也可以理解為變成了 absolute 定位),所以當頁面超過一屏且滾動時,失效的 fixed 元素就會跟隨滾動了。
這便是 iOS 上 fixed 元素和輸入框的 bug 。其中不僅限於 type=text
的輸入框,凡是軟鍵盤(比如時間日期選擇、select 選擇等等)被喚起,都會遇到同樣地問題。
雖然 isScroll.js
可以很好的解決 fixed 定位滾動的問題,但是不在萬不得已的情況下,我們儘量嘗試一下不依賴第三方庫的佈局方案,以簡化實現方式。這裡拋磚引玉作為參考。
解決思路:
既然在 iOS 下由於軟鍵盤喚出後,頁面 fixed 元素會失效,導致跟隨頁面一起滾動,那麼假如——頁面不會過長出現滾動,那麼即便 fixed 元素失效,也無法跟隨頁面滾動,也就不會出現上面的問題了。
那麼按照這個思路,如果使 fixed 元素的父級不出現滾動,而將原 body 滾動的區域域移到 main 內部,而 header 和 footer 的樣式不變,程式碼如下:
|
|
這樣再來看一下:
fixed定位
在原始輸入法下, fixed 元素可以定位在頁面的正確位置。滾動頁面時,由於滾動的是 main 內部的 div,因此 footer 沒有跟隨頁面滾動。
上面貌似解決了問題,但是如果在手機上實際測試一下,會發現 main 元素內的滾動非常不流暢,滑動的手指鬆開後,滾動立刻停止,失去了原本的流暢滾動特性。百度一下彈性滾動的問題,發現在 webkit
中,下面的屬性可以恢復彈性滾動。
-webkit-overflow-scrolling: touch;
在 main 元素上加上該屬性,嗯,絲般順滑的感覺又回來了!
|
另外,這裡的 header 和 footer 使用的是 fixed 定位,如果考慮到更老一些的 iOS 系統不支援 fixed 元素,完全可以把 fixed 替換成 absolute 。測試後效果是一樣的。
至此一個不依賴第三方庫的 fixed 佈局就完成了。
Android 下佈局
談到了 iOS ,也來簡單說一下 Android 下的佈局吧。
在 Android2.3+ 中,因為不支援 overflow-scrolling ,因此部分瀏覽器內滾動會有不流暢的卡頓。但是目前發現在 body 上的滾動還是很流暢的,因此使用第一種在 iOS 出現問題的 fixed 定位的佈局就可以了。
如果需要考慮 Android2.3 以下系統,因為不支援 fixed 元素,所以依然要需要考慮使用 isScroll.js
來實現內部滾動。
其實在 fixed 和輸入框的問題上,基本思路就是: > 由於 fixed 在軟鍵盤喚起後會失效,導致在頁面可以滾動時,會跟隨頁面一起滾動。因此如果頁面無法滾動,那麼 fixed 元素即使失效,也不會滾動,也就不會出現 bug 了。
所以可以在這個方面去考慮解決問題。
其他的一些細節處理
在細節處理上,其實還有很多要注意的,挑幾個實際遇到比較大的問題來說一下: