Web移動端Fixed布局的解決方案

2022-09-20 03:51:13 字數 3817 閱讀 9861

移動端業務開發,ios 下經常會有 fixed 元素和輸入框(input 元素)同時存在的情況。 但是 fixed 元素在有軟鍵盤喚起的情況下,會出現許多莫名其妙的問題。 這篇文章裡就提供乙個簡單的有輸入框情況下的 fixed 布局方案。

ios下的 fixed + input bug現象

讓我們先舉個栗子,最直觀的說明一下這個 bug 的現象。 常規的 fixed 布局,可能使用如下布局(以下僅示意**):

1

<

body

class

="layout-fixed"

>23

<

header

>45

header

>67

8<

main

>910

main

>

1112

13<

footer

>

14<

input

type

="text"

placeholder

="footer..."

/>

15<

button

class

="submit"

>提交

button

>

16footer

>

17body

>

對應的樣式如下:

1

header, footer, main 45

header

1213

footer

2021

main

然後看起來就是下面這個樣子。拖動頁面時 header 和 footer 已經定位在了對應的位置,目測沒問題了。

但接下來問題就來了!如果底部輸入框軟鍵盤被喚起以後,再次滑動頁面,就會看到如下圖所示:

我們看到 fixed 定位好的元素跟隨頁面滾動了起來… fixed 屬性失效了!

這是為什麼呢?簡單解釋下: > 軟鍵盤喚起後,頁面的 fixed 元素將失效(即無法浮動,也可以理解為變成了 absolute 定位),所以當頁面超過一屏且滾動時,失效的 fixed 元素就會跟隨滾動了。

這便是 ios 上 fixed 元素和輸入框的 bug 。其中不僅限於 type=text 的輸入框,凡是軟鍵盤(比如時間日期選擇、select 選擇等等)被喚起,都會遇到同樣地問題。

雖然 isscroll.js 可以很好的解決 fixed 定位滾動的問題,但是不在萬不得已的情況下,我們盡量嘗試一下不依賴第三方庫的布局方案,以簡化實現方式。這裡拋磚引玉作為參考。

解決思路:

既然在 ios 下由於軟鍵盤喚出後,頁面 fixed 元素會失效,導致跟隨頁面一起滾動,那麼假如——頁面不會過長出現滾動,那麼即便 fixed 元素失效,也無法跟隨頁面滾動,也就不會出現上面的問題了。

那麼按照這個思路,如果使 fixed 元素的父級不出現滾動,而將原 body 滾動的區域域移到 main 內部,而 header 和 footer 的樣式不變,**如下:

1

<

body

class

="layout-scroll-fixed"

>23

<

header

>45

header

>67

8<

main

>

9<

div

class

="content"

>

1011

div>

12main

>

1314

15<

footer

>

16<

input

type

="text"

placeholder

="footer..."

/>

17<

button

class

="submit"

>提交

button

>

18footer

>

19body

>

header, footer, main header footer main main .content
這樣再來看一下:

在原始輸入法下, fixed 元素可以定位在頁面的正確位置。滾動頁面時,由於滾動的是 main 內部的 div,因此 footer 沒有跟隨頁面滾動。

main
另外,這裡的 header 和 footer 使用的是 fixed 定位,如果考慮到更老一些的 ios 系統不支援 fixed 元素,完全可以把 fixed 替換成 absolute 。測試後效果是一樣的。

至此乙個不依賴第三方庫的 fixed 布局就完成了。

其他的一些細節處理

在細節處理上,其實還有很多要注意的,挑幾個實際遇到比較大的問題來說一下:

有時候輸入框 focus 以後,會出現軟鍵盤遮擋輸入框的情況,這時候可以嘗試 input 元素的 scrollintoview 進行修復。

在 ios 下使用第三方輸入法時,輸入法在喚起經常會蓋住輸入框,只有在輸入了一條文字後,輸入框才會浮出。目前也不知道有什麼好的辦法能讓喚起輸入框時正確顯示。這暫時算是 ios 下的乙個坑吧。

有些第三方瀏覽器底部的工具欄是浮在頁面之上的,因此底部 fixed 定位會被工具欄遮擋。解決辦法也比較簡單粗暴——適配不同的瀏覽器,調整 fixed 元素距離底部的距離。

最好將 header 和 footer 元素的 touchmove 事件禁止,以防止滾動在上面觸發了部分瀏覽器全屏模式切換,而導致頂部位址列和底部工具欄遮擋住 header 和 footer 元素。

在頁面滾動到上下邊緣的時候,如果繼續拖拽會將整個 view 一起拖拽走,導致頁面的「露底」。

為了防止頁面露底,可以在頁面拖拽到邊緣的時候,通過判斷拖拽方向以及是否為邊緣來阻止 touchmove 事件,防止頁面繼續拖拽。

以上面內滾動 layout-scroll-fixed 布局為例,給出一段**作為參考:

1

// 防止內容區域滾到底後引起頁面整體的滾動

2var content = document.queryselector('main');

3var starty;45

content.addeventlistener('touchstart', function (e) );89

content.addeventlistener('touchmove', function (e) else if (ele.scrolltop + ele.offsetheight >= ele.scrollheight)

2526

if (status != '11') 33}

34 });

Web移動端Fixed布局的解決方案

移動端業務開發,ios 下經常會有 fixed 元素和輸入框 input 元素 同時存在的情況。但是 fixed 元素在有軟鍵盤喚起的情況下,會出現許多莫名其妙的問題。這篇文章裡就提供乙個簡單的有輸入框情況下的 fixed 布局方案。讓我們先舉個栗子,最直觀的說明一下這個 bug 的現象。常規的 f...

Web移動端Fixed布局的解決方案

移動端業務開發,ios 下經常會有 fixed 元素和輸入框 input 元素 同時存在的情況。但是 fixed 元素在有軟鍵盤喚起的情況下,會出現許多莫名其妙的問題。這篇文章裡就提供乙個簡單的有輸入框情況下的 fixed 布局方案。讓我們先舉個栗子,最直觀的說明一下這個 bug 的現象。常規的 f...

Web移動端Fixed布局的解決方案

移動端業務開發,ios 下經常會有 fixed 元素和輸入框 input 元素 同時存在的情況。但是 fixed 元素在有軟鍵盤喚起的情況下,會出現許多莫名其妙的問題。這篇文章裡就提供乙個簡單的有輸入框情況下的 fixed 布局方案。讓我們先舉個栗子,最直觀的說明一下這個 bug 的現象。常規的 f...