閱讀本文的收穫:爲何個人小程序組件不能隨着頁面滾動?爲何組件層級不對?我該如何解決?css
在平常開發中,咱們總能在小程序的開發文檔裏看到種種組件:前端
基礎組件:小程序框架層開發ios
自定義組件:開發者or小程序官方,基於基礎組件
進行二次開發web
動態庫組件:小程序官方開發的、以動態庫形式發佈的組件,其本質依然是自定義、基礎組件
canvas
......小程序
綜上:就像是蓋樓,框架開發的基礎組件
,是小程序全部組件建築的地基,咱們今天要聊的正是它。瀏覽器
基礎組件實現
前置名詞解釋
NA:
Native App
的縮寫,是基於智能手機本地操做系統如iOS、Android、WP
並使用原生程式編寫運行的第三方應用程序,通常開發語言爲JAVA、C++、Objective-C、Swift
前端框架
NA 組件:也稱原生組件,是
Android、ios
等NA
客戶端開發的控件框架
H5組件:是指
HTML5
語言編寫的web
組件ide
webview:用來在
NA
代碼中展現web
頁面,有點相似web中的iframe
,ios、Android
中分別採起WKWebView
和WebView
控件實現。
前置特性解釋
小程序前端框架,會將開發者實現的小程序佈局轉換成標準
HTML
佈局;
NA
組件與webview
在兩個層級(以下圖1.1)在客戶端代碼中,後插入的
NA
組件,層級高於以前的NA
組件
框架層的基礎組件,是基於H5
組件和NA
組件實現的。
好比小程序中的 canvas、map、animation-view、textarea、cover-view、cover-image、camera、video、live-player、input
這些都是原生組件。
相比於H5
組件,NA
組件不只能夠提供H5
組件沒法實現的一些功能,還能提高用戶體驗上的流暢度,又由於減小了客戶端代碼與webview
通訊的流程,下降了通訊開銷。
簡單來講,NA
組件功能全、速度快、開銷少;然而,命運贈送的禮物,早已在暗中標好了價格——原生組件並非十全十美,它付出了其餘代價。
圖1.1
因爲原生組件脫離在 webview
渲染流程外,所以在使用時有如下限制:
-
原生組件的層級是最高的:頁面中的其餘組件不管設置
z-index
爲多少,都沒法蓋在原生組件上; -
部分 CSS 樣式沒法應用於原生組件;
-
原生組件沒法在
scroll-view
、swiper
、picker-view
、movable-view
中使用:由於若是開發者在可滾動的DOM
區域,插入原生組件做爲其子節點,因爲原生組件是直接插入到webview
外部的層級,與DOM
之間沒有關聯,因此不會跟隨移動也不會被裁減
這也就解釋了,爲何你在使用一些原生組件時,會出現組件不隨着頁面滾動或是層級永遠最高的bug。
.......是否是有點難搞?
解決NA的限制
解決這個問題不是一蹴而就的,它也有本身的歷史進程:
cover-image
和cover-view
,是局部解決方案:因爲在客戶端中,後插入的原生組件層級高於前面的原生組件,因此把想覆蓋原生組件的內容,用一個原生組件包裹後插入,從而hack
解決。
但這樣作,就像是寫css
的時候,寫了一堆!important
,並非一個優雅的解決方案,後面提到的同層渲染纔是終極大殺器。
同層渲染
爲了解決原生組件的層級問題,同時儘量保留 NA 組件的優點,小程序客戶端、前端及瀏覽內核團隊一塊兒制定了一套解決方案:因爲此方案的控件並不是繪製在 NA
貼片層,而是繪製在 WebView
所渲染的頁面中,與其餘 HTML
控件在同一層級,所以稱爲「同層渲染」;在支持同層渲染後,原生組件與其它H5
組件能夠隨意疊加,層級的限制將不復存在。
Android 同層渲染原理
前置特性解釋
T7:T7內核是百度手機瀏覽器基於Blink研發的瀏覽內核
ZeusPlugin:T7瀏覽器內核的一個插件機制,可用來解析或發送前端、客戶端指令,做爲二者通訊的中樞
swanCore:小程序前端框架
小程序在 Android
端採用 T7
瀏覽內核做爲渲染層,內核提供了 ZeusPlugin
指令系統。
-
由
SwanCore
將開發者實現的小程序佈局轉換成標準HTML
佈局,並對同層渲染的組件增長標識; -
T7
瀏覽內核渲染頁面時,識別到標識,則認爲此組件爲同層組件; -
T7
瀏覽內核根據需求爲同層組件擴展方法和屬性,供前端SwanCore
調用; -
擴展的能力部分由瀏覽內核實現,也可經過小程序客戶端的能力實現,根據能力具體內容而定。
ios 同層渲染原理
前置名詞
WKWebView:
NA
組件,用來在NA
代碼中展現web
頁面,它在內部採用的是分層方式進行渲染
Compositing Layer:NA合成層,內核通常會將多個
webview
內的DOM
節點渲染到一個Compositing Layer
上,所以合成層與DOM
節點之間不存在一對一的映射關係
WKChildScrollView:也是NA組件,但
WebKit
內核已經處理了它與其餘DOM
節點之間的層級關係,與webview
內的DOM
節點存在映射關係
前置特性
當把一個
webview
內的DOM
節點的CSS
屬性設置爲overflow: scroll
(低版本需同時設置-webkit-overflow-scrolling: touch
)以後,NA
的WKWebView
會爲其生成一個對應的WKChildScrollView
iOS
端同層渲染,也正是基於 WKChildScrollView
實現的,大體流程以下:
-
小程序前端,在
webview
內建立一個DOM
節點並設置其 CSS 屬性爲overflow: hidden
且-webkit-overflow-scrolling: touch
; -
前端通知客戶端查找到該
DOM
節點對應的原生WKChildScrollView
組件; -
將原生組件掛載到該
WKChildScrollView
節點上做爲其子View
; -
WebKit
內核已經處理了WKChildScrollView
與對應DOM
節點之間的層級關係。 -
經過上述流程,小程序的
NA
組件就被插入到WKChildScrollView
了,也便是在 步驟1 建立的那個DOM
節點映射的原生WKChildScrollView
節點。此時,修改這個DOM
節點的樣式屬性一樣也會應用到原生組件上。所以,同層渲染的原生組件與普通的H5
組件表現並沒有二致。
使用組件的注意事項
-
NA組件中支持同層渲染的狀況(同時須要注意的是,同層渲染會存在失敗的狀況,若是嘗試5次以後依舊失敗,依舊會採用NA組件的方式)
組件名 | 支持版本 |
---|---|
video | v3.70.0 起 |
input | v3.105.0 起 |
textarea | v3.140.1起 |
live-player | v3.140.1 起 |
-
未支持同層渲染的
NA
組件或者較低版本,須要注意上文提到的原生組件的使用限制:
-
原生組件的層級是最高的,因此頁面中的其餘組件不管設置 z-index 爲多少,都沒法蓋在原生組件上。後插入的原生組件能夠覆蓋以前的原生組件;
-
原生組件沒法在 scroll-view、swiper、picker-view、movable-view 中使用;
-
沒法對原生組件設置 CSS 動畫;
-
不能在父級節點使用 overflow: hidden 來裁剪原生組件的顯示區域
3.如需在NA組件中增長更高層級的組件,可考慮使用cover-image、cover-view
- END -