小程序應(yīng)用中WebView中原生組件限制問(wèn)題解析
『由于原生組件脫離在 WebView 渲染流程外,因此在操作時(shí)有以下束縛:
原生組件的層級(jí)是最高的,所以頁(yè)面中的其他組件無(wú)論設(shè)置 z-index 為多少,都無(wú)法蓋在原生組件上。
后插入的原生組件可以覆蓋之前的原生組件。
原生組件還無(wú)法在 scroll-view、swiper、picker-view、movable-view 中操作。
部分CSS樣式無(wú)法應(yīng)用于原生組件,例如:
無(wú)法對(duì)原生組件設(shè)置 CSS 動(dòng)畫(huà)
無(wú)法定義原生組件為 position: fixed
不能在父級(jí)節(jié)點(diǎn)操作 overflow: hidden 來(lái)裁剪原生組件的顯示區(qū)域
原生組件的事件監(jiān)聽(tīng)不能操作 bind:eventname 的寫(xiě)法,只支持 bindeventname。原生組件也不支持 catch 和 capture 的事件綁定方式
在iOS下,原生組件暫時(shí)不支持觸摸相關(guān)事件。
在工具上,原生組件是用web組件模擬的,因此很多情況并不能很好的還原真機(jī)的表現(xiàn),意見(jiàn)搭建者在操作到原生組件時(shí)盡量在真機(jī)上進(jìn)行調(diào)試?!?/p>
所謂的原生組件,即非Web組件軟件擴(kuò)展Native組件。因?yàn)槲⑿判〕绦蛟谝晥D渲染層面操作了WebView,而在Video,Map這類(lèi)組件,操作WebView的WebCore渲染之后體驗(yàn)不佳的詬病一直存在,而且標(biāo)準(zhǔn)不一。微信小程序上因操作原生的WebView進(jìn)行渲染,而不是用修改的WebView內(nèi)核(至少在iOS上沒(méi)有這么干),而無(wú)法對(duì)web原生標(biāo)簽擴(kuò)展?;谟脩?hù)體驗(yàn),和坑爹的技術(shù)束縛,微信小程序提出了原生組件的概念,也就是在WebView上面操作原生組件填充占位元素的方式修補(bǔ)這類(lèi)組件用戶(hù)體驗(yàn)問(wèn)題。因?yàn)閃ebView和原生組件在應(yīng)用層本身就不是一個(gè)渲染層級(jí),于是出現(xiàn)Web上面的標(biāo)簽無(wú)法浮于Video之上(直播應(yīng)用的惡夢(mèng)),在不修改技術(shù)思路的前提下,position: fixed, overflow: hidden這樣的屬性是不可能用于原生組件的樣式的。不過(guò)偽同層渲染也不是說(shuō)不可能,即在渲染原生組件時(shí)候根據(jù)層級(jí)鏤空面積。
特別在Map上操作WebView作為渲染之后體驗(yàn)不佳的詬病一直存在,特別是地圖上marker標(biāo)記過(guò)多的重度場(chǎng)景下,筆者所在的企業(yè)的在操作高德地圖Web端提供出來(lái)的C端具備反人類(lèi)的體驗(yàn),地圖拖拉龜速,點(diǎn)擊響應(yīng)緩慢,加載loading地圖區(qū)域等待時(shí)間過(guò)長(zhǎng)。而Video則支持的格式局限,列出部分瀏覽器的支持的如下:
- Firefox:支持 Ogg Vorbis和WAV
- Opera :支持Ogg Vorbis和WAV
- Safari :支持MP3,AAC格式 ,和MP4
- Chrome :支持Ogg Vorbis,MP3,WAV,AAC和MP4
- Internet Explorer 9+ :支持MP3,AAC格式 ,和MP4
- IOS :支持MP3,AAC格式 ,和MP4
- Android :支持AAC和MP3
上述,可以知道視頻支持局限(限于版權(quán))。而就咱們關(guān)注的無(wú)線端iOS和Andoroid,實(shí)現(xiàn)一個(gè)視頻播放,咱們可能都會(huì)有以下幾點(diǎn)的需要:
1、全屏處理; 2、覆蓋層效果; 3、自動(dòng)播放; 4、播放控制; 5、隱藏播放控件;
在iOS上如果操作WebView,你無(wú)法修改全屏下的工具這一點(diǎn)體驗(yàn)已經(jīng)足夠讓所有的產(chǎn)品經(jīng)理抓狂,更不用說(shuō)Android的這么多的機(jī)型。覆蓋層效果在微信上不得不操作微信提供原生組件cover-view實(shí)現(xiàn),而限于原生實(shí)現(xiàn)束縛,cover-view的支持局限。
1、組件層于WebView層之上 這也應(yīng)該是微信小程序團(tuán)隊(duì)現(xiàn)階段操作的規(guī)劃,通過(guò)特殊的占位標(biāo)簽,操作getBoundingClientRect獲取組件位置,而原生組件跟隨Webview滾動(dòng)。 Talking is cheap. Show me your code,那么用代碼實(shí)現(xiàn)的效果的如下。
now_lowest_gif.gif
從圖中可見(jiàn),覆蓋層確實(shí)位于原生組件之下。
2、組件層于WebView層之下 此方式略微復(fù)雜。需要通過(guò)與Webview scroll聯(lián)動(dòng)的置于Webview之下的Component Layer實(shí)現(xiàn),而Webview背景設(shè)置為透明。至于事件,通過(guò)Webview的事件透?jìng)?,傳遞到Component Layer,需要通過(guò)緩存webview中元素再計(jì)算是否被點(diǎn)中通過(guò)重寫(xiě)hitTest方法實(shí)現(xiàn)。通過(guò)此技術(shù)規(guī)劃實(shí)現(xiàn)的好處也是明顯的,因?yàn)樵M件層很多時(shí)候都是置于最底層,而Web上的組件可以輕松覆蓋于Native之上,無(wú)需操作cover-view之類(lèi)的hack方法。 效果如下所示
圖片發(fā)自簡(jiǎn)書(shū)App Tips 在iOS上還特別需要注意一點(diǎn)UIWebview的坑。在操作-webkit-overflow-scrolling 操作,你會(huì)發(fā)現(xiàn)momentum scroll階段并不會(huì)觸發(fā)scroll事件,而且 scrollTop 屬性不會(huì)變化,當(dāng)然getBoundingClientRect也同樣失效。如果考慮操作touchmove 這樣事件你也僅僅在手指還在屏幕上的時(shí)候觸發(fā),檢測(cè)滾動(dòng)區(qū)域內(nèi)部元素的getBoundingClientRect 同樣無(wú)效。
當(dāng)然幸運(yùn)的是,這么大一個(gè)坑只是發(fā)生在UIWebview,對(duì)WKWebview并沒(méi)有影響。
第二部分:如何開(kāi)通一個(gè)小商店