寫在前面
MIP 中懸浮元素的特殊情況
其實組件上線已經有一段時間了,最開始看到這個需求是站長提交了一個這中功能的組件過來,不過看過代碼立刻就想到了 MIP 頁面的特殊性:從結果頁打開的 MIP 頁面,是嵌套在一個 iframe 之中的。
在這種特殊的情況下,單純的通過 position: fixed 去實現 DOM 元素的懸浮存在一系列的問題。比如,在 ios 的 safari 瀏覽器中,當用戶滑動頁面的時候,頁面中的懸浮元素會隨著頁面的滑動而閃爍。
因此,MIP 提供了 mip-fixed 懸浮布局組件來解決這些問題。
滑動懸浮的使用場景
顧名思義就是一個 DOM 節點在滑動的一定位置的時候,變為懸浮狀態。滑動懸浮的使用場景還是很多的,比如一些頁面中的導航,當導航滑動到頁面頂部的時候則懸浮在頁面頂部,以方便用戶操作。如:

業界技術實現與存在的問題
業界技術實現
目前業內針對這種滾動頁面定位的情況一般使用兩種邏輯來寫:
(1)將懸浮前后的兩個狀態分成兩個 dom 節點(暫時叫做 staticDOM 和 fixedDOM),并通過 JavaScript 控制兩個 dom 節點的顯示和隱藏。在頁面到達懸浮狀態之前:staticDOM 節點顯示,fixedDOM 節點隱藏;到達懸浮狀態之后:staticDOM 節點隱藏,fixedDOM 節點顯示。
- 優點:JavaScript 邏輯簡單
- 缺點:html 代碼冗余
(2)只需要一個 dom 節點(暫時叫做 stickyDOM),所有的邏輯都通過 JavaScript 控制,也就是說,頁面到達懸浮狀態的時候,將 stickyDOM 的 CSS 樣式中的 position 屬性的值設置為 fixed, 非懸浮狀態的時候,將 stickyDOM 的 CSS 樣式中的 position 屬性設置為 static。
- 優點:html 代碼清晰
- 缺點:由于每個頁面之間的特性,比較難達到通用性
(3)通過 CSS3 的 position: sticky 實現。這是 CSS3 的新特性,不過目前還不能達到很好的兼容狀態,特別是我們這種在 iframe 內的特殊情況。關于 sticky 可以參考文檔 position:sticky實現iOS6+下的粘性布局
仍然存在的問題
在 ios 下的 uc、百度和手百瀏覽器中,無論采用哪種方法,由于瀏覽器原因,頁面滑動的時候,所有的 JavaScript 都無法實時計算并執行。因此,只有當頁面滑動停止后,JavaScript 才能去計算頁面的位置,然后處理懸浮元素的狀態,這樣就會看到懸浮元素狀態的變化有卡頓的情況,對此,目前并沒有十分好的解決辦法,如果大家有更好的辦法,可以反饋我們。
簡介
mip-semi-fixed 是滑動懸浮組件,也可以叫做半懸浮組件,命名為 semi-fixed 的靈感來源于半導體(介于導體(conductor)與絕緣體(insulator)之間)。
代碼設計融合了業界兩種實現方案,非 SF 下 MIP 頁面中通過 JavaScript 更換 CSS 實現,iframe下的 MIP 頁面由于要特殊處理 fixed 元素,所以會克隆一個 dom 節點,具體代碼參考 mip-semi-fixed 開源代碼。
屬性及節點
threshold 屬性(非必選項)
元素 fixed 狀態時距離頁面頂部的距離,默認是 0。
fixedClassNames 屬性(非必選項)
元素 fixed 狀態時需要添加的類,如果沒有這個屬性,則 組件只會懸浮不會改變樣式。
div[mip-semi-fixed-container] 子節點(必選項)
需要滑動后懸浮的 html 代碼的容器,組件科隆的也是這個節點。
MIP 官網文檔 mip-semi-fixed 滑動懸浮組件 中對組件各個參數的說明、使用以及默認值等進行了詳細的說明。
使用
常規使用
- 代碼:傳送門
- 示例:傳送門
加關閉按鈕
- 代碼:傳送門
- 示例:傳送門
寫在后面
有任何問題可以到 github issues 提問。
文章作者:Pearl
轉發自segmentfault