mui初级入门教程(六)— 模板页面实现原理及多端适配指南
文章來源:小青年原創
發布時間:2016-07-26
關鍵詞:mui,webview,template,os,多端適配
轉載需標注本文原始地址: http://zhaomenghuan.github.io...
寫在前面
自從來公司實習,每天都淹沒在問題中,一直沒有抽出空寫寫文章,今天輪到我完善文檔和總結,就想著抽空把文檔中的內容寫寫,但是文檔限于篇幅,而且不能話嘮,自然博客是最好的方式去分享。哈哈,廢話不多說,將整理的內容貼出來,稍作解釋,方便大家查閱。
template(模板頁面)
hello mui示例App中無等待窗體切換的實現是基于模板頁面,點擊一個鏈接,不顯示雪花等待框,立即打開一個“正在加載...”的頁面,之后真實內容快速填充“正在加載...”區域。這種模板頁面適用了通用性較強的頁面,我們不必要為每個頁面創建父子webview,而是將公用的父頁面提取出來作為模板頁面,同時在頁面為加載前可以顯示個性化加載頁面,可以極大的提升用戶體驗。模板父頁面預加載,點擊后立即顯示,不用展示雪花等待框,也不會出現白屏現象;共用子頁面,有效控制webview數量,避免切頁時頻繁創建、銷毀webview。
實現思路
這里我們以列表到詳情頁的情況為例說明,詳情頁html結構:
<ul class="mui-table-view"><li class="mui-table-view-cell"><a class="mui-navigate-right" href="list1.html"> Item 1 </a> </li> <li class="mui-table-view-cell"> <a class="mui-navigate-right" href="list2.html"> Item 2 </a> </li> <li class="mui-table-view-cell"> <a class="mui-navigate-right" href="list3.html"> Item 3 </a> </li> </ul>1.預加載一個模板父頁面,用以當頁面還沒有加載出來的時候展示加載動畫,以及作為公用子頁面的頭部,原理相當于tabbar webview模式的父頁面;預加載或者創建一個公用子頁面,同時將這個子頁面填充到模板父頁面;
// 預加載模板父頁面 var template = mui.preload({url:'template.html',id:'template',styles:{popGesture:"hide" } }); // 預加載公用子頁面 var subWebview = mui.preload({ url:'', id:'sub_template', styles:{ top: '45px', bottom: '0px' } }); // 將子頁面填充到父頁面 template.append(subWebview);2.點擊列表鏈接時,直接顯示模板父頁面,并動態修改模板父頁面的標題;共用子頁面通過loadURL方法加載對應目標頁面;
mui('.mui-table-view').on('tap','li a',function(){ var self = this; // 修改共用父模板的標題 mui.fire(template, 'updateHeader', { title: self.innerText, href: self.href }); // 加載子頁面地址 if(subWebview.getURL()==self.href){ subWebview.show(); }else{ subWebview.loadURL(self.href); // 子頁面加載完成顯示 subWebview.addEventListener('loaded', function() { setTimeout(function(){ subWebview.show(); },50); }); } // 顯示模板父頁面 template.show('slide-in-right', 150); })3.模板父頁面接收參數和返回列表頁的處理方法
var titleElem = document.getElementById("title"); var contentWebview = null,self = null; mui.plusReady(function () { self = plus.webview.currentWebview(); }); // 自定義事件接收參數修改模板父頁面頭部 window.addEventListener("updateHeader", function(e) { var title = e.detail.title; var href = e.detail.target; var aniShow = e.detail.aniShow; titleElem.innerHTML = title; titleElem.className = "mui-title mui-fadein"; if(mui.os.android&&aniShow&&parseFloat(mui.os.version)>=4.4){ if(contentWebview==null){ contentWebview = self.children()[0]; } if (contentWebview.getURL() != href) { contentWebview.loadURL(href); } else { contentWebview.show(); } setTimeout(function () { self.show(aniShow); },10); } }); // 返回事件(隱藏模板父頁面,并在窗體動畫結束后,隱藏共用子頁面) mui.back = function() { self.hide('auto'); setTimeout(function() { titleElem.className = 'mui-title mui-fadeout'; titleElem.innerText = ''; if(contentWebview==null){ contentWebview = self.children()[0]; } contentWebview.hide("none"); }, 350); }另外需要說明的是,我們這種方式是創建兩個webview作為視圖容器實現,在web環境下webview的方法不能執行,hello mui里面為每個詳情頁面創建一個頭部,但是我們會發現在app環境下執行并沒有出現這個頭部,這是以為在hello mui演示demo中的app.css中有這么一段代碼:
.mui-plus.mui-android header.mui-bar{ display: none; } .mui-plus.mui-android .mui-bar-nav~.mui-content{ padding: 0; }由于iOS系統性能已經足夠好,轉場切換不會白屏,hello mui演示demo中iOS沒有使用模板頁面。當我們引入mui.js文件,在5+環境執行,mui.js會自動將.mui-plus及.mui-plus-android類添加到body上,我們可以通過這個方法進行環境判斷,是否顯示某些內容。
運行環境判斷
如果是寫文檔,寫到上面自然就戛然而止,但是寫文章,希望把這個相關的問題順便多聊幾句,因為一旦有人遇到相關的問題,多說了幾句就說不定解決的。
說到系統判斷,這里不得不說一下mui.os這個工具方法,mui通過封裝html5中的navigator.userAgentAPI進行判斷系統和版本號:
-
5+環境下判斷方法:
-
mui.os.plus 返回是否在5+基座中運行
等效于:navigator.userAgent.indexOf("Html5Plus")>-1 -
mui.os.stream 返回是否為流應用
等效于:navigator.userAgent.indexOf("StreamApp")>-1
-
-
Android環境下判斷方法:
-
mui.os.android 返回是否為安卓手機
等效于:navigator.userAgent.indexOf("Android")>-1 -
mui.os.isBadAndroid android非Chrome環境
等效于:!(/Chrome\/\d/.test(window.navigator.appVersion)) -
mui.os.version 安卓版本
等效于:navigator.userAgent.match(/(Android);?[\s\/]+([\d.]+)?/)[2]
-
-
IOS環境下判斷方法:
-
mui.os.ios 返回是否為蘋果設備
等效于:navigator.userAgent.indexOf("iPhone")>-1&&navigator.userAgent.indexOf("iPad")>-1 -
mui.os.iphone 返回是否為蘋果手機
等效于:navigator.userAgent.indexOf("iPhone")>-1 -
mui.os.ipad 返回是否為ipad
等效于:navigator.userAgent.indexOf("iPad")>-1 -
mui.os.version 返回手機版本號
等效于:navigator.userAgent.match(/(iPhone\sOS)\s([\d_]+)/).[2].replace(/_/g, '.')||navigator.userAgent.match(/(iPad\sOS)\s([\d_]+)/).[2].replace(/_/g, '.')
-
-
微信環境下判斷方法:
-
mui.os.wechat 返回是否為微信端
等效于:navigator.userAgent.indexOf("MicroMessenger")>-1 -
mui.os.wechat.version 返回微信版本
等效于:navigator.userAgent.match(/(MicroMessenger)\/([\d\.]+)/i)[2].replace(/_/g, '.')
-
這里我們可以通過mui.os.*方法進行判斷,但是很多時候我們需要更簡單的方法去判斷,比如我們希望某一部分內容只在5+環境下顯示,有些內容只在非5+環境下執行,或者有些內容只在微信環境下使用,使用mui.os.*有時候顯得還是不夠方便,那這里就說一個更簡單的方法,就是我們上面講到的通過設置class類的CSS方法。
讀mui源碼我們能夠知道,mui中定義mui.os.*系列方法,同時通過mui.os.*方法判斷環境,將.mui-plus,.mui-plus-stream,.mui-ios,.mui-android,.mui-wechat,mui-ios-version,mui-android-version,mui-wechat-version綁定在document.body.classList中,我們可以通過這些樣式類判斷當前的運行判斷,于是可以做出一些適配。
.mui-plus-visible, .mui-wechat-visible{display: none!important; } .mui-plus-hidden, .mui-wechat-hidden{ display: block!important; } .mui-plus .mui-plus-visible, .mui-wechat .mui-wechat-visible{ display: block!important; } .mui-plus .mui-tab-item.mui-plus-visible, .mui-wechat .mui-tab-item.mui-wechat-visible{ display: table-cell!important; } .mui-plus .mui-plus-hidden, .mui-wechat .mui-wechat-hidden{ display: none!important; }當我們知道這些類的時候,在做適配的時候可以解決很多小問題,如下面這個例子:
<div class="mui-input-row mui-plus-visible"><label>mui-plus-visible</label> <input type="text" class="mui-input-speech mui-input-clear" placeholder="我在web環境下隱藏5+環境下顯示"> </div> <div class="mui-input-row mui-plus-hidden"> <label>mui-plus-hidden</label> <input type="text" class="mui-input-clear" placeholder="我在web環境下顯示5+環境下隱藏"> </div>我們可以使用.mui-plus-visible將只能在5+環境下正常使用的內容在web環境下隱藏,反過來我們可以使用 .mui-plus-hidden將在web中正常顯示的內容在5+環境下隱藏。在5+環境下我們使用增強版的語音輸入,在普通web環境下使用h5的普通輸入框。
開發一次,多端發布,我想這種很多人希望看到的,目前mui中很多組件已經實現在多平臺自動切換到合適的模式,使用最合適的姿勢,但是對于業務要求各不相同的開發者,想要實現多端發布,不是簡單的一兩句的問題,還是得熟悉各個平臺的差異化,同時對于h5,mui,html5+中的實現方法的差異要所有了解的前提下,才能夠做到真正的多端發布。
多端發布注意事項
上面講解了多端發布的時候系統及版本判斷的方法,但是依然沒有說明區別所在,估計很多人看了依然是懵逼狀態。為解決HTML5在低端Android機上的性能缺陷,mui引入了原生加速,在普通瀏覽器端5+的一些方法不再適用,所以做多端發布的時候必須先明白哪一些方法可以使用,哪一些不能使用。因此如果不是APP端,需要將5+的方法全部替換成h5的方法。
mui中最關鍵的5+模塊是webview控件,因此mui若要發揮其全部能力,凡是涉及到webview窗體的內容在非5+環境不能使用,涉及功能點包括:
-
webview模式窗體動畫
-
創建子窗口(除了為解決區域滾動的常見雙webview場景,還涉及webview模式的選項卡等多webview場景)
-
webview模式的側滑菜單(也有div方式側滑菜單)
-
webview模式的tab選項卡(也有div方式選項卡)
-
nativeUI,如原生的警告框、確認框、popover、actionsheet、toast。這些也有HTML5的實現。
-
預加載
-
頁面傳值(拓展參數及自定義事件)
對于這部分的內容,解決方法也有很多,如果mui提供了iframe模式的父子頁面(主要兼容上拉加載下拉刷新),div模式的、側滑菜單、選項卡、彈出框,頁面傳值也可以使用url傳參或localStorage等本地存儲的方法。在mui初級入門教程(二)— html5+ webview 底部欄用法詳解一文中我也給出了iframe兼容webview模式tabbar的解決方法。
對于第三方插件,html5+中的方法可以優雅降級處理,采用h5的相關標準去實現,比如dcloud官方給出了一個定位的例子,查看這里plusto,plusto是為實現多端發布的一個開源JS庫,該庫可以根據平臺實現API的自動轉換,比如在5+ App環境下,將瀏覽器默認定位升級為5+原生定位,實現一套代碼平滑遷移至多個平臺。在微信中有jssdk同樣可以調用系統的一些功能,大家可以自行判斷。
或許有些人喜歡使用一些構建工具,對于多端發布使用構建工具確實會很方便,但是對于小白用戶來說,可能會遇到更多問題,DCloud的mui及Hello mui示例是使用grunt構建的,grunt相關配置也都開源,感興趣的朋友可以自行構建,后面有時間再整理一篇相關的文章加以說明。
參考文章
hello mui中的無等待窗體切換是如何實現的
mui適用場景說明,能不能在普通瀏覽器里使用,能否用于wap網站
多端發布開發指南
后記
這篇文章基本都是copy相關的文檔,加以增刪,乃成此文。好久不寫文,大神勿噴!
最后放上demo地址:
mui-demo:https://github.com/zhaomenghu...
轉載于:https://www.cnblogs.com/PheonixHkbxoic/p/6013368.html
新人創作打卡挑戰賽發博客就能抽獎!定制產品紅包拿不停!總結
以上是生活随笔為你收集整理的mui初级入门教程(六)— 模板页面实现原理及多端适配指南的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 星战7将映 追忆那些年存储你身边大数据
- 下一篇: 【云周刊】第128期:支撑千亿营收背后秘