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