mui入門教程

mui入門教程

資源索引

 

 

官方分類文檔

 

html5+是什麼?

html5+DCloud提供的html5強化引擎,可以把HTML5 App打包爲原生App,並且達到原生的功能和體驗。說白了就是原本只能原生APP才能實現的功能,現在可以通過html5+這個強化引擎作爲橋樑,你通過調用plus.*方法實現,也就是你可以通過書寫js代碼實現android和ios兩套的原生功能。html5+封裝了一些最常用的功能,並向W3C提交了作爲標準的提案,具體的可以參考html5+規範API

html5+和native.js有什麼區別?

html5+作爲一種通用標準,只封裝了最常用的一些API,如果你有其他需求但是5+裏面沒有怎麼辦,這個時候如果你懂原生應用開發,你可以基於native.js語法規範進行個性化封裝。Native.js for Android封裝一條通過JS語法直接調用Native Java接口通道,通過plus.android可調用幾乎所有的系統APINative.js for iOS封裝一條通過JS語法直接調用Native Objective-C接口通道,通過plus.ios可調用幾乎所有的系統API

5+ sdk是什麼?

我們經常看到html5+(即html5plus)、5+ sdk,其實本質是一樣的,不過這裏的5+ sdk是針對離線打包開發和Hybrid開發模式,因爲用hbuilder在線打包,html5+native.js的底層會被自動打包到安裝包裏面,開發者無需引用什麼即可調用相關API。只要當開發者想要離線打包及Hybrid開發模式或者深入瞭解html5+的引擎實現原理,才需要去了解一下5+ sdk,一般情況下我們只需要知道5+標準裏面的基本用法就足夠我們開發出一個APP

mui與html5+有什麼關係?

muiDcloud官方推出的一個基於html5+標準的框架,同時擁有h5組件和原生組件,原生組件依賴於html5+運行環境,也就是原生app裏面的webview組件(能加載顯示網頁,可以將其視爲一個瀏覽器),所以mui裏面的原生組件不能用於瀏覽器環境,可以通過mui裏面的mui.os.plus進行判斷,如果是plus環境會返回true,否則會返回undefined。開發者可以根據自己的需要進行代碼適配,對於APP使用增強的原生組件,對於普通瀏覽器裏面運行的頁面使用h5組件。同時用戶還可以使用mui.os.androidmui.os.iosmui.os.wechat對平臺進行檢測,然後書寫不同的邏輯代碼。對於mui裏面沒有封裝的原生組件,大家可以根據自己的需要基於html5+標準和native.js語法進行個性化定製。因此這裏我們可以有一個基本影響就是我們開始可以直接上手mui,不過需要明白mui與其他UI框架的區別在於,mui擁有獨有的原生組件,而且這個是依賴於html5+標準的,所以mui裏面的很多組件實現方法甚至用戶就是html5+裏面的標準寫法,對html5+標準有一定了解有助於我們理解mui的一些使用方法。

 

webview基本知識

 

Webview模塊管理應用窗口界面,實現多窗口的邏輯控制管理操作。通過plus.webview可獲取應用界面管理對象。

 

什麼是窗口?什麼是webview?

 

這裏我們首先來舉個例子,大家都用過瀏覽器,常用的瀏覽器可以打開多個網頁。電腦屏幕就是一個窗口,不同的頁面我們可以什麼是不同的webview,我們可以通過控制webview的切換從而控制瀏覽不同的頁面。

 

對於我們這裏就是一個html頁面就是一個窗口,一個html頁面可以創建多個webview。這個webview是原生APP中瀏覽網頁的組件,android和iOS都有,html5plus中的webview是對原生webview的封裝,可以用js進行調用,所以它的運行環境是APP環境,普通瀏覽器不支持。

 

首先我們現在html5plus官網看一下webview API文檔,這裏我們重點看一下下面幾個方法:

 

創建新的Webview窗口

WebviewObject plus.webview.create( url, id, styles, extras );

說明:

創建Webview窗口,用於加載新的HTML頁面,可通過styles設置Webview窗口的樣式,創建完成後需要調用show方法才能將Webview窗口顯示出來。

顯示Webview窗口

plus.webview.show( id_wvobj, aniShow, duration, showedCB, extras );

說明:

顯示已創建或隱藏的Webview窗口,需先獲取窗口對象或窗口id,並可指定顯示窗口的動畫及動畫持續時間。

隱藏Webview窗口

void plus.webview.hide( id_wvobj, aniHide, duration, extras );

說明:

根據指定的WebviewObject對象或id隱藏Webview窗口,使得窗口不可見。 

獲取當前窗口的WebviewObject對象

WebviewObject plus.webview.currentWebview();

說明: 

獲取當前頁面所屬的Webview窗口對象。

查找指定標識的WebviewObject窗口

WebviewObject plus.webview.getWebviewById( id );

說明:

在已創建的窗口列表中查找指定標識的Webview窗口並返回。 若沒有查找到指定標識的窗口則返回null,若存在多個相同標識的Webview窗口,則返回第一個創建的Webview窗口。 如果要獲取應用入口頁面所屬的Webview窗口,其標識爲應用的%APPID%,可通過plus.runtime.appid獲取。

創建並打開Webview窗口 

WebviewObject plus.webview.open( url, id, styles, aniShow, duration, showedCB );

說明:

創建並顯示Webview窗口,用於加載新的HTML頁面,可通過styles設置Webview窗口的樣式,創建完成後自動將Webview窗口顯示出來。 

 

以上來源於html5plus文檔,只列舉了部分最常用的方法,旨在爲後文做鋪墊,由於不是文檔,所以也得也不清楚,如果想詳細瞭解請看這裏html5plus webview API。 

mui雙webview模式

 

首先我們要了解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;特別注意,heightwidth兩個屬性,即使不設置,也默認按100%計算;因此若設置了top值爲非"0px"的情況,建議同時設置bottom值,否則5+ runtime根據高度100%計算,可能會造成頁面真實底部位置超出屏幕範圍的情況,leftright同理。

  • 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.backvar 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()觸發自定義事件

按照文檔的說明我們知道有三個參數:(不知道文檔在哪裏的請戳這裏【文檔】

mui.fire( target , event , data )

target爲你要傳入數據的那個webview,我們這裏是要出入到父webview,由於我們沒有給父webview指定id,我們前面知道這樣就不方便拿到父webview對象,這裏就使用當前webviewparent()間接獲取。
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;      //接下來這裏拿到數據後寫邏輯代碼了...});

複製代碼


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章