MUI視窗管理

來源:互聯網
上載者:User

標籤:

1、頁面初始化

  在app開發中,若要使用HTML5+擴充api,必須等plusready事件發生後才能正常使用,mui將該事件封裝成了mui.plusReady()方法,涉及到HTML5+的api,建議都寫在mui.plusReady方法中。如下為列印當前頁面URL的樣本:

mui.plusReady(function(){    console.log("當前頁面URL:"+plus.webview.currentWebview().getURL());});mui.init()    mui外掛程式初始化mui.ready()    當DOM準備就緒時,指定一個函數來執行。

代碼塊啟用字元: minit


2、建立子頁面

   在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同理。

樣本:Hello mui的首頁其實就是index.html加list.html合并而成的,如下:


  index.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,可不定義;      }    }]  });


代碼塊啟用字元: misubpage


3、開啟新頁面

  做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,//等待框背景地區高度,預設根據內容自動計算合適高度        ......      }    }})


參數:

(1)、styles

   視窗參數,參考5+規範中的WebviewStyle;特別注意,height和width兩個屬性,即使不設定,也預設按100%計算;因此若設定了top值為非"0px"的情況,建議同時設定bottom值,否則5+ runtime根據高度100%計算,可能會造成頁面真實底部位置超出螢幕範圍的情況;left、right同理。

(2)、extras

   新視窗的額外擴充參數,可用來處理頁面間傳值;例如:

var webview = mui.openWindow({url:'info.html',extras:{name:'mui'  //擴充參數}});console.log(webview.name);//輸出mui字串

注意:擴充參數僅在開啟新視窗時有效,若目標視窗為預先載入頁面,則通過mui.openWindow方法開啟時傳遞的extras參數無效。

(3)、createNew

   是否重複建立相同id的webview;為最佳化效能、避免app中重複建立webview,mui v1.7.0開始增加createNew參數,預設為false;判斷邏輯如下:

    a、createNew參數為為true,則不判斷重複,每次都建立webview;

    b、createNew參數為為fasle,則先尋找當前App中是否已存在同樣id的webview,若存在則直接顯示;否則新建立並根據show參數執行顯示邏輯;

   注意:plusReady事件僅在webview首次建立時觸發,使用mui.openWindow方法多次開啟已存在的同樣id的webview時,是不會重複觸發plusReady事件的; 因此若業務寫在plusReady事件中,可能會出現執行結果和預期不一致的情況;此時可通過自訂事件觸發。

(4)、show

  視窗顯示控制參數,具體參數如下:

    a、autoShow:目標視窗loaded事件發生後,是否自動顯示,預設為true;若為false,則僅建立但不顯示webview;若目標頁面為預先載入頁面,則該參數無效;

   b、aniShow表示頁面顯示動畫,比如從右側劃入、從下側劃入等,具體可參考5+規範中的AnimationTypeShow

   c、duration:顯示Webview視窗動畫的期間,單位為ms

(5)、waiting

  系統等待框參數。mui架構在開啟新頁面時等待框的處理邏輯為:顯示等待框-->建立目標頁面webview-->目標頁面loaded事件發生-->關閉等待框;因此,只有當新頁面為新建立頁面(webview)時,會顯示等待框,否則若為預先載入好的頁面,則直接顯示目標頁面,不會顯示等待框。waiting中的具體參數:

   a、autoShow:是否自動顯示等待框,預設為true;若為false,則不顯示等待框;注意:若waiting框的autoShow為true,但目標頁面不自動顯示,則需在目標頁面中通過如下代碼關閉等待框:plus.nativeUI.closeWaiting();

   b、title:等待框上的提示文字

   c、options表示等待框顯示參數,比如寬高、背景色、提示文字顏色等,具體可參考5+規範中的WaitingOption

樣本1:Hello mui中,點擊首頁右上方的表徵圖,會開啟關於頁面,實現代碼如下:

//tap為mui封裝的單擊事件,可參考手勢事件章節document.getElementById('info').addEventListener('tap', function() {  //開啟關於頁面  mui.openWindow({    url: 'examples/info.html',    id:'info'  });});

因沒有傳入styles參數,故預設全螢幕顯示;也沒有傳入show參數,故使用slide-in-right動畫,新頁面從右側滑入。

樣本2:從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();  });}

代碼塊啟用字元: mopenwindow

 

4、關閉頁面

   mui架構將視窗關閉功能封裝在mui.back方法中,具體執行邏輯是:若當前webview為預先載入頁面,則hide當前webview;否則,close當前webview;

在mui架構中,有三種操作會觸發頁面關閉(執行mui.back方法):

 a、點擊包含.mui-action-back類的控制項

 b、在螢幕內,向右快速滑動

 c、Android手機按下back按鍵

 iOS平台原生支援從螢幕邊緣右滑關閉。iOS平台可通過popGesture參數實現從螢幕邊緣右滑關閉webview,參考5+規範,若想禁用該功能,可通過setStyle方法設定popGesture為none。

  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(){//獲得列表介面的webviewvar 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();    }  });}

  為何設定了swipeBack: false,在iOS上依然可以右滑關閉?iOS平台原生支援從螢幕邊緣右滑關閉,這個是通過popGesture參數控制的,參考5+規範,若需禁用,可通過setStyle方法設定popGesture為none。

  能否通過addEventListener增加back按鍵監聽實現自訂關閉邏輯?addEventListener只會增加新的執行邏輯,老的監聽邏輯(mui.back)依然會執行,因此,若需實現自訂關閉邏輯,一定要重寫mui.back。

代碼塊啟用字元: mback

 

5、預先載入

   所謂的預先載入技術就是在使用者尚未觸發頁面跳轉時,提前建立目標頁面,這樣當使用者跳轉時,就可以立即進行頁面切換,節省建立新頁面的時間,提升app使用體驗。mui提供兩種方式實現頁面預先載入。

(1)、方式一:通過mui.init方法中的preloadPages參數進行配置.

mui.init({  preloadPages:[    {      url:prelaod-page-url,      id:preload-page-id,      styles:{},//視窗參數      extras:{},//自訂擴充參數      subpages:[{},{}]//預先載入頁面的子頁面    }  ],  preloadLimit:5//預先載入視窗數量限制(一旦超出,先進先出)預設不限制});

  該種方案使用簡單、可預先載入多個頁面,但不會返回預先載入每個頁面的引用,若要獲得對應webview引用,還需要通過plus.webview.getWebviewById方式獲得;另外,因為mui.init是非同步執行,執行完mui.init方法後立即獲得對應webview引用,可能會失敗,例如如下代碼:

mui.init({  preloadPages:[    {      url:'list.html',      id:'list'    }  ]});var list = plus.webview.getWebviewByid('list');//這裡可能返回空;

(2)、方式二:通過mui.preload方法預先載入.

var page = mui.preload({    url:new-page-url,    id:new-page-id,//預設使用當前頁面的url作為id    styles:{},//視窗參數    extras:{}//自訂擴充參數});

   通過mui.preload()方法預先載入,可立即返回對應webview的引用,但一次僅能預先載入一個頁面;若需載入多個webview,則需多次調用mui.preload()方法;

如上兩種方案,各有優劣,需根據具體業務情境靈活選擇;

(3)、判斷預先載入是否成功

方式一、通過直觀現象分析

    預先載入頁面會立即開啟,不會顯示等待框;非預先載入頁面預設會先顯示等待框,再顯示新頁面;

方式二、增加log分析預先載入頁面是否已建立

    比如:A頁面中預先載入B頁面,則在A頁面完全載入(可通過setTimeout類比)後,列印當前應用所有webview,看是否包含B頁面的url,以此來分析。

例如:在A頁面增加如下代碼:

mui.plusReady(function(){setTimeout(function(){var array = plus.webview.all();if(array){for(var i=0,len=array.length;i<len;i++){    console.log(array[i].getURL());        }}},5000)});

代碼塊啟用字元: minitpreload  mpreload(單個webview)

MUI視窗管理

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.