Dcloud官網:http://dcloud.io/html
Dcloud問答社區:http://ask.dcloud.net.cn/前端
Dcloud文檔彙總地址:http://ask.dcloud.net.cn/docs/html5
Hello mui線上演示地址:http://www.dcloud.io/hellomui...android
官方入門文檔(強烈推薦閱讀):ios
DCloud產品概述git
App入門開發github
mui產品web
新手指南ajax
案例彙總:http://dcloud.io/case/json
github地址:https://github.com/dcloudio/
html5+官網文檔:http://www.html5plus.org/doc/
5+ App開發Native.js入門指南:http://ask.dcloud.net.cn/arti...
Native.js示例彙總:http://ask.dcloud.net.cn/arti...
流應用開發指南:http://ask.dcloud.net.cn/arti...
html5+
是DCloud
提供的html5
強化引擎,能夠把HTML5 App
打包爲原生App
,而且達到原生的功能和體驗。說白了就是本來只能原生APP
才能實現的功能,如今能夠經過html5+
這個強化引擎做爲橋樑,你經過調用plus.*
方法實現,也就是你能夠經過書寫js代碼實現android和ios兩套的原生功能。html5+
封裝了一些最經常使用的功能,並向W3C
提交了做爲標準的提案,具體的能夠參考html5+規範API。
html5+
做爲一種通用標準,只封裝了最經常使用的一些API
,若是你有其餘需求可是5+裏面沒有怎麼辦,這個時候若是你懂原生應用開發,你能夠基於native.js
語法規範進行個性化封裝。Native.js for Android
封裝一條經過JS
語法直接調用Native Java
接口通道,經過plus.android
可調用幾乎全部的系統API
。Native.js for iOS
封裝一條經過JS
語法直接調用Native Objective-C
接口通道,經過plus.ios
可調用幾乎全部的系統API
。
咱們常常看到html5+
(即html5plus
)、5+ sdk
,其實本質是同樣的,不過這裏的5+ sdk是針對離線打包開發和Hybrid
開發模式,由於用hbuilder
在線打包,html5+
和native.js
的底層會被自動打包到安裝包裏面,開發者無需引用什麼便可調用相關API。只要當開發者想要離線打包及Hybrid
開發模式或者深刻了解html5+
的引擎實現原理,才須要去了解一下5+ sdk
,通常狀況下咱們只須要知道5+標準裏面的基本用法就足夠咱們開發出一個APP
。
mui
是Dcloud
官方推出的一個基於html5+
標準的框架,同時擁有h
5組件和原生組件,原生組件依賴於html5+
運行環境,也就是原生app
裏面的webview
組件(能加載顯示網頁,能夠將其視爲一個瀏覽器),因此mui
裏面的原生組件不能用於瀏覽器環境,能夠經過mui
裏面的mui.os.plus
進行判斷,若是是plus
環境會返回true
,不然會返回undefined
。開發者能夠根據本身的須要進行代碼適配,對於APP
使用加強的原生組件,對於普通瀏覽器裏面運行的頁面使用h5
組件。同時用戶還可使用mui.os.android
、mui.os.ios
及mui.os.wechat
對平臺進行檢測,而後書寫不一樣的邏輯代碼。對於mui
裏面沒有封裝的原生組件,你們能夠根據本身的須要基於html5+
標準和native.js
語法進行個性化定製。所以這裏咱們能夠有一個基本影響就是咱們開始能夠直接上手mui
,不過須要明白mui
與其餘UI
框架的區別在於,mui
擁有獨有的原生組件,並且這個是依賴於html5+
標準的,因此mui
裏面的不少組件實現方法甚至用戶就是html5+
裏面的標準寫法,對html5+
標準有必定了解有助於咱們理解mui
的一些使用方法。
Webview模塊管理應用窗口界面,實現多窗口的邏輯控制管理操做。經過plus.webview可獲取應用界面管理對象。
這裏咱們首先來舉個例子,你們都用過瀏覽器,經常使用的瀏覽器能夠打開多個網頁。電腦屏幕就是一個窗口,不一樣的頁面咱們能夠什麼是不一樣的webview,咱們能夠經過控制webview的切換從而控制瀏覽不一樣的頁面。
對於咱們這裏就是一個html頁面就是一個窗口,一個html頁面能夠建立多個webview。這個webview是原生APP中瀏覽網頁的組件,android和iOS都有,html5plus中的webview是對原生webview的封裝,能夠用js進行調用,因此它的運行環境是APP環境,普通瀏覽器不支持。
首先咱們如今html5plus官網看一下webview API文檔,這裏咱們重點看一下下面幾個方法:
WebviewObject plus.webview.create( url, id, styles, extras );
建立Webview窗口,用於加載新的HTML頁面,可經過styles設置Webview窗口的樣式,建立完成後須要調用show方法才能將Webview窗口顯示出來。
plus.webview.show( id_wvobj, aniShow, duration, showedCB, extras );
顯示已建立或隱藏的Webview窗口,需先獲取窗口對象或窗口id,並可指定顯示窗口的動畫及動畫持續時間。
void plus.webview.hide( id_wvobj, aniHide, duration, extras );
根據指定的WebviewObject對象或id隱藏Webview窗口,使得窗口不可見。
WebviewObject plus.webview.currentWebview();
獲取當前頁面所屬的Webview窗口對象。
WebviewObject plus.webview.getWebviewById( id );
在已建立的窗口列表中查找指定標識的Webview窗口並返回。 若沒有查找到指定標識的窗口則返回null,若存在多個相同標識的Webview窗口,則返回第一個建立的Webview窗口。 若是要獲取應用入口頁面所屬的Webview窗口,其標識爲應用的%APPID%,可經過plus.runtime.appid獲取。
WebviewObject plus.webview.open( url, id, styles, aniShow, duration, showedCB );
建立並顯示Webview窗口,用於加載新的HTML頁面,可經過styles設置Webview窗口的樣式,建立完成後自動將Webview窗口顯示出來。
以上來源於html5plus文檔,只列舉了部分最經常使用的方法,旨在爲後文作鋪墊,因爲不是文檔,因此也得也不清楚,若是想詳細瞭解請看這裏html5plus webview API。
首先咱們要了解mui爲了解決窗體切換白屏和區域滾動提出的雙webview模式。
mui框架將不少功能配置都集中在mui.init
方法中,要使用某項功能,只須要在mui.init
方法中完成對應參數配置便可,目前支持在mui.init
方法中配置的功能包括:建立子頁面、關閉頁面、手勢事件配置、預加載、下拉刷新、上拉加載、設置系統狀態欄背景顏色。mui須要在頁面加載時初始化不少基礎控件,如監聽返回鍵,所以務必在每一個頁面中調用.
mui.init({ //子頁面 subpages: [{ //... }], //預加載 preloadPages:[ //... ], //下拉刷新、上拉加載 pullRefresh : { //... }, //手勢配置 gestureConfig:{ //... }, //側滑關閉 swipeBack:true, //Boolean(默認false)啓用右滑關閉功能 //監聽Android手機的back、menu按鍵 keyEventBind: { backbutton: false, //Boolean(默認truee)關閉back按鍵監聽 menubutton: false //Boolean(默認true)關閉menu按鍵監聽 }, //處理窗口關閉前的業務 beforeback: function() { //... //窗口關閉前處理其餘業務詳情點擊 ↑ "關閉頁面"連接查看 }, //設置狀態欄顏色 statusBarBackground: '#9defbcg', //設置狀態欄顏色,僅iOS可用 preloadLimit:5//預加載窗口數量限制(一旦超出,先進先出)默認不限制 })
在app
開發中,若要使用HTML5+
擴展api
,必須等plusready
事件發生後才能正常使用,mui將該事件封裝成了mui.plusReady()
方法,涉及到HTML5+
的api
,建議都寫在mui.plusReady
方法中。
以下爲打印當前頁面URL的示例:
mui.plusReady(function(){ console.log("當前頁面URL:"+plus.webview.currentWebview().getURL()); });
在mobile app開發過程當中,常常遇到卡頭卡尾的頁面,此時若使用局部滾動,在android手機上會出現滾動不流暢的問題; mui的解決思路是:將須要滾動的區域經過單獨的webview實現,徹底使用原生滾動。具體作法則是:將目標頁面分解爲主頁面和內容頁面,主頁面顯示卡頭卡尾區域,好比頂部導航、底部選項卡等;內容頁面顯示具體須要滾動的內容,而後在主頁面中調用mui.init方法初始化內容頁面。
mui.init({ subpages:[{ url:your-subpage-url,//子頁面HTML地址,支持本地地址和網絡地址 id:your-subpage-id,//子頁面標誌 styles:{ top:subpage-top-position,//子頁面頂部位置 bottom:subpage-bottom-position,//子頁面底部位置 width:subpage-width,//子頁面寬度,默認爲100% height:subpage-height,//子頁面高度,默認爲100% ...... }, extras:{}//額外擴展參數 }] });
styles:表示窗口屬性,參考5+規範中的WebviewStyle;特別注意,height和width兩個屬性,即便不設置,也默認按100%計算;所以若設置了top值爲非"0px"的狀況,建議同時設置bottom值,不然5+ runtime根據高度100%計算,可能會形成頁面真實底部位置超出屏幕範圍的狀況;left、right同理。
ndex.html的做用就是顯示固定導航,list.html顯示具體列表內容,列表項的滾動是在list.html所在webview中使用原生滾動,既保證了滾動條不會穿透頂部導航,符合app的體驗,也保證了列表流暢滾動,解決了區域滾動卡頓的問題。 list.html就是index.html的子頁面,建立代碼比較簡單,以下:
mui.init({ subpages:[{ url:'list.html', id:'list.html', styles:{ top:'45px',//mui標題欄默認高度爲45px; bottom:'0px'//默認爲0px,可不定義; } }] });
作web app
,一個沒法避開的問題就是轉場動畫;web
是基於連接構建的,從一個頁面點擊連接跳轉到另外一個頁面,若是經過有刷新的打開方式,用戶要面對一個空白的頁面等待;若是經過無刷新的方式,用Javascript
移入DOM節點(常見的SPA
解決方案),會碰到很高的性能挑戰:DOM節點繁多,頁面太大,轉場動畫不流暢甚至致使瀏覽器崩潰; mui的解決思路是:單webview
只承載單個頁面的dom,減小dom層級及頁面大小;頁面切換使用原生動畫,將最耗性能的部分交給原生實現。
mui.openWindow({ url:new-page-url, id:new-page-id, styles:{ top:newpage-top-position,//新頁面頂部位置 bottom:newage-bottom-position,//新頁面底部位置 width:newpage-width,//新頁面寬度,默認爲100% height:newpage-height,//新頁面高度,默認爲100% ...... }, extras:{ .....//自定義擴展參數,能夠用來處理頁面間傳值 }, createNew:false,//是否重複建立一樣id的webview,默認爲false:不重複建立,直接顯示 show:{ autoShow:true,//頁面loaded事件發生後自動顯示,默認爲true aniShow:animationType,//頁面顯示動畫,默認爲」slide-in-right「; duration:animationTime//頁面動畫持續時間,Android平臺默認100毫秒,iOS平臺默認200毫秒; }, waiting:{ autoShow:true,//自動顯示等待框,默認爲true title:'正在加載...',//等待對話框上顯示的提示內容 options:{ width:waiting-dialog-widht,//等待框背景區域寬度,默認根據內容自動計算合適寬度 height:waiting-dialog-height,//等待框背景區域高度,默認根據內容自動計算合適高度 ...... } } })
styles:表示窗口參數,參考5+規範中的WebviewStyle;特別注意,height
和width
兩個屬性,即便不設置,也默認按100%
計算;所以若設置了top
值爲非"0px"
的狀況,建議同時設置bottom
值,不然5+ runtime
根據高度100%
計算,可能會形成頁面真實底部位置超出屏幕範圍的狀況,left
、right
同理。
extras:新窗口的額外擴展參數,可用來處理頁面間傳值;例如:
var webview = mui.openWindow({ url:'info.html', extras:{ name:'mui' } }); console.log(webview.name);
控制檯會輸出"mui"字符串;
注意:擴展參數僅在打開新窗口時有效,若目標窗口爲預加載頁面,則經過mui.openWindow方法打開時傳遞的extras參數無效。
createNew:是否重複建立相同id的webview
;爲優化性能、避免app中重複建立webview,mui v1.7.0開始增長createNew
參數,默認爲false;判斷邏輯以下:若createNew爲true,則不判斷重複,每次都新建webview
;若爲fasle,則先計算當前App中是否已存在一樣id的webview,若存在則直接顯示;不然新建立並根據show參數執行顯示邏輯;該參數可能致使的影響:若業務寫在plusReady
事件中,而plusReady
事件僅首次建立時會觸發,則下次再次經過mui.openWindow
方法打開一樣webview時,是不會再次觸發plusReady
事件的,此時可經過自定義事件觸發;案例參考:http://ask.dcloud.net.cn/question/6514
;
show:表示窗口顯示控制。autoShow:目標窗口loaded事件發生後,是否自動顯示;若目標頁面爲預加載頁面,則該參數無效;aniShow表示頁面顯示動畫,好比從右側劃入、從下側劃入等,具體可參考5+規範中的AnimationTypeShow。
waiting:表示系統等待框;mui框架在打開新頁面時等待框的處理邏輯爲:顯示等待框-->建立目標頁面webview-->目標頁面loaded事件發生-->關閉等待框;所以,只有當新頁面爲新建立頁面(webview)時,會顯示等待框,不然若爲預加載好的頁面,則直接顯示目標頁面,不會顯示等待框。waiting中的參數:autoShow表示自動顯示等待框,默認爲true,若爲false,則不顯示等待框;注意:若顯示了等待框,但目標頁面不自動顯示,則需在目標頁面中經過以下代碼關閉等待框plus.nativeUI.closeWaiting()
;。title表示等待框上的提示文字,options表示等待框顯示參數,好比寬高、背景色、提示文字顏色等,具體可參考5+規範中的WaitingOption。
示例:從A頁面打開B頁面,B頁面爲一個須要從服務端加載的列表頁面,若在B頁面loaded事件發生時就將其顯示出來,因服務器數據還沒有加載完畢,列表頁面爲空,用戶體驗很差;可經過以下方式改善用戶體驗(最好的用戶體驗應該是經過預加載的方式)
第一步,B頁面loaded事件發生後,不自動顯示
//A頁面中打開B頁面,設置show的autoShow爲false,則B頁面在其loaded事件發生後,不會自動顯示; mui.openWindow({ url: 'B.html', show:{ autoShow:false } });
第二步,在B頁面獲取列表數據後,再關閉等待框、顯示B頁面
//B頁面onload從服務器獲取列表數據; window.onload = function(){ //從服務器獲取數據 .... //業務數據獲取完畢,並已插入當前頁面DOM; //注意:若爲ajax請求,則需將以下代碼放在處理完ajax響應數據以後; mui.plusReady(function(){ //關閉等待框 plus.nativeUI.closeWaiting(); //顯示當前頁面 mui.currentWebview.show(); }); }
mui框架將窗口關閉功能封裝在mui.back方法中,具體執行邏輯是:
若當前webview爲預加載頁面,則hide當前webview;不然,close當前webview。
在mui框架中,有三種操做會觸發頁面關閉(執行mui.back方法)。
點擊包含.mui-action-back類的控件
在頁面上,向右快速滑動
Android手機按下back按鍵
hbuilder中敲mheader生成的代碼塊,會自動生成帶有返回導航箭頭的標題欄,點擊返回箭頭可關閉當前頁面,緣由就是由於該返回箭頭包含.mui-action-back類,代碼以下:
<header class="mui-bar mui-bar-nav"> <a class="mui-action-back mui-icon mui-icon-left-nav mui-pull-left"></a> <h1 class="mui-title">標題</h1> </header>
若但願在頂部導航欄以外的其它區域添加關閉頁面的控件,只須要在對應控件上添加.mui-action-back類便可,以下爲一個關閉按鈕示例:
<button type="button" class='mui-btn mui-btn-danger mui-action-back'>關閉</button>
mui框架封裝的頁面右滑關閉功能,默認未啓用,若要使用右滑關閉功能,須要在mui.init()
;方法中設置swipeBack
參數,以下:
mui.init({ swipeBack:true //啓用右滑關閉功能 });
mui框架默認會監聽Android手機的back按鍵,而後執行頁面關閉邏輯; 若不但願mui自動處理back按鍵,可經過以下方式關閉mui的back按鍵監聽;
mui.init({ keyEventBind: { backbutton: false //關閉back按鍵監聽 } });
除了如上三種操做外,也能夠直接調用mui.back()
方法,執行窗口關閉邏輯;mui.back()
僅處理窗口邏輯,若但願在窗口關閉以前再處理一些其它業務邏輯,則可將業務邏輯抽象成一個具體函數,而後註冊爲mui.init
方法的beforeback
參數;beforeback
的執行邏輯爲:
執行beforeback
參數對應的函數若返回false,則再也不執行mui.back()方法;不然(返回true或無返回值),繼續執行mui.back()方法;
示例:從列表打開詳情頁面,從詳情頁面再返回後但願刷新列表界面,此時可註冊beforeback參數,而後經過自定義事件通知列表頁面刷新數據,示例代碼以下:
mui.init({ beforeback: function(){ //得到列表界面的webview var list = plus.webview.getWebviewById('list'); //觸發列表界面的自定義事件(refresh),從而進行數據刷新 mui.fire(list,'refresh'); //返回true,繼續頁面關閉邏輯 return true; } });
注意:beforeback
的執行返回必須是同步的(阻塞模式),若使用nativeUI
這種異步js(非阻塞模式),則可能會出現意想不到的結果;好比:經過plus.nativeUI.confirm()
彈出確認框,可能用戶還沒有選擇,頁面已經返回了(beforeback
同步執行完畢,無返回值,繼續執行mui.back()
方法,nativeUI
不會阻塞js進程):在這種狀況下,若要自定義業務邏輯,就須要複寫mui.back
方法了;以下爲一個自定義示例,每次都須要用戶確認後,纔會關閉當前頁面。
//備份mui.back,mui.back已將窗口關閉邏輯封裝的比較完善(預加載及父子窗口),所以最好複用mui.back var old_back = mui.back; mui.back = function(){ var btn = ["肯定","取消"]; mui.confirm('確認關閉當前窗口?','Hello MUI',btn,function(e){ if(e.index==0){ //執行mui封裝好的窗口關閉邏輯; old_back(); } }); }
注意:自定義關閉邏輯時,必定要重寫mui.back
,不能簡單經過addEventListener
增長back按鍵監聽, 由於addEventListener
只會增長新的執行邏輯,老的監聽邏輯依然會執行;
按照文檔的說明咱們知道有三個參數:(不知道文檔在哪裏的請戳這裏【文檔】)
mui.fire( target , event , data )
target爲你要傳入數據的那個webview
,咱們這裏是要出入到父webview
,因爲咱們沒有給父webview
指定id
,咱們前面知道這樣就不方便拿到父webview
對象,這裏就使用當前webview
的parent()
間接獲取。
event是你能夠指定的自定義事件名稱。
data是你要傳入的數據,爲json
格式 (不知道json爲什麼物的同窗請戳我上一篇文章mui初級入門教程(三)— html5+ XMLHttpRequest 與mui ajax用法詳解) 。
咱們獲取數據也很簡單:
// 添加targetTab自定義事件監聽 window.addEventListener('targetTab',function(event){ // 得到選項卡點擊事件參數 var targetTitle = event.detail.targetTitle; var targetTab = event.detail.targetTab; //接下來這裏拿到數據後寫邏輯代碼了... });
不過這裏有一個特別須要注意的問題,因爲我尚未遇到,可是看官網文檔有說明,貼出來方便後來遇到這個問題的同窗:
目標webview必須觸發loaded事件後才能使用自定義事件
若新建立一個webview,不等該webview的loaded事件發生,就當即使用webview.evalJS()或mui.fire(webview,'eventName',{}),則可能無效;案例參考:這裏
用mui作webapp除了前端基礎知識外,我以爲最關鍵的就是要掌握理解webview以及頁面間的傳值問題,本文原始地址:
【MUI從入門到精通】專欄地址: