HTML5 極簡的JS函數

頁面初始化

mui框架將不少功能配置都集中在mui.init方法中,要使用某項功能,只須要在mui.init方法中完成對應參數配置便可,目前支持在mui.init方法中配置的功能包括:建立子頁面、關閉頁面、手勢事件配置、預加載、下拉刷新、上拉加載。javascript

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

mui.plusReady(function(){ console.log("當前頁面URL:"+plus.webview.currentWebview().getURL()); });

          

建立子頁面

在mobile app開發過程當中,常常遇到卡頭卡尾的頁面,此時若使用局部滾動,在android手機上會出現滾動不流暢的問題; mui的解決思路是:將須要滾動的區域經過單獨的webview實現,徹底使用原生滾動。具體作法則是:將目標頁面分解爲主頁面和內容頁面,主頁面顯示卡頭卡尾區域,好比頂部導航、底部選項卡等;內容頁面顯示具體須要滾動的內容,而後在主頁面中調用mui.init方法初始化內容頁面。css

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

示例:Hello mui的首頁其實就是index.html加list.html合併而成的,以下:html5

          
index.html
+
         
list.html
=
        
合併後的首頁

index.html的做用就是顯示固定導航,list.html顯示具體列表內容,列表項的滾動是在list.html所在webview中使用原生滾動,既保證了滾動條不會穿透頂部導航,符合app的體驗,也保證了列表流暢滾動,解決了區域滾動卡頓的問題。 list.html就是index.html的子頁面,建立代碼比較簡單,以下:java

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層級及頁面大小;頁面切換使用原生動畫,將最耗性能的部分交給原生實現.android

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

參數說明:git

  • 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+規範中的WaitingOptiongithub

示例1:Hello mui中,點擊首頁右上角的圖標,會打開關於頁面,實現代碼以下:web

//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(); }); }

      

關閉頁面

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只會增長新的執行邏輯,老的監聽邏輯依然會執行;

      

Ajax

mui框架基於htm5plus的XMLHttpRequest,封裝了經常使用的Ajax函數,支持GET、POST請求方式,支持返回json、xml、html、text、script數據類型; 本着極簡的設計原則,mui提供了mui.ajax方法,並在mui.ajax方法基礎上,進一步簡化出最經常使用的mui.get()、mui.getJSON()、mui.post()三個方法。

mui.ajax()方法經過HTTP請求加載遠程數據,是mui框架底層Ajax的實現方法,使用方法:mui.ajax(url[,setting]),其中url表示請求發送的目標地址,setting是一個json對象,支持的參數主要包括:

參數 類型 描述
data Object 發送到服務器的數據,能夠是json對象或字符串
dataType String 預期服務器返回的數據類型;若是不指定,mui將自動根據HTTP包的MIME頭信息自動判斷;支持設置的dataType可選值:
  • "xml": 返回XML文檔
  • "html": 返回純文本HTML信息;
  • "script": 返回純文本JavaScript代碼
  • "json": 返回JSON數據
  • "text": 返回純文本字符串
error Function 請求失敗時觸發的函數,該函數接收三個參數:
  • xhr:xhr實例對象,類型是XMLHttpRequest
  • type:錯誤描述,類型是String,可取值除了'null'外,其它可能值:"timeout", "error", "abort", "parsererror"
  • errorThrown:可捕獲的異常對象,類型是String
success Function 請求成功時觸發的回調函數,該函數接收三個參數:
  • data:服務器返回的響應數據,類型能夠是json對象、xml對象、字符串等;
  • textStatus:狀態描述,參數類型是String,默認值爲'success'
  • xhr:xhr實例對象,類型是XMLHttpRequest
timeout Number 請求超時時間(毫秒),默認值爲0,表示永不超時;若超過設置的超時時間(非0的狀況),依然未收到服務器響應,則觸發error回調
type String 請求方式,目前僅支持'GET'和'POST',默認爲'GET'方式

代碼示例:以下爲經過post方式向某服務器發送鑑權登陸的代碼片斷

mui.ajax('http://server-name/login.php',{ data:{ username:'username', password:'password' }, dataType:'json',//服務器返回json格式數據 type:'post',//HTTP請求類型 timeout:10000,//超時時間設置爲10秒; success:function(data){ //服務器返回響應,根據響應結果,分析是否登陸成功; ... }, error:function(xhr,type,errorThrown){ //異常處理; console.log(type); } });

mui.post()方法是對mui.ajax()的一個簡化方法,直接使用POST請求方式向服務器發送數據、且不處理timeout和異常(若需處理異常及超時,請使用mui.ajax()方法),使用方法: mui.post(url[,data][,success][,dataType]),如上登陸鑑權代碼換成mui.post()後,代碼更爲簡潔,以下:

mui.post('http://server-name/login.php',{ username:'username', password:'password' },function(data){ //服務器返回響應,根據響應結果,分析是否登陸成功; ... },'json' );

mui.get()方法和mui.post()方法相似,只不過是直接使用GET請求方式向服務器發送數據、且不處理timeout和異常(若需處理異常及超時,請使用mui.ajax()方法),使用方法: mui.get(url[,data][,success][,dataType]),以下爲得到某服務器新聞列表的代碼片斷,服務器以json格式返回數據列表

mui.get('http://server-name/list.php',{category:'news'},function(data){ //得到服務器響應 ... },'json' );

如上mui.get()方法和以下mui.ajax()方法效果是一致的:

 

mui.ajax('http://server-name/list.php',{ data:{ category:'news' }, dataType:'json',//服務器返回json格式數據 type:'get',//HTTP請求類型 success:function(data){ //得到服務器響應 ... } });

mui.getJSON()方法是在mui.get()方法基礎上的更進一步簡化,限定返回json格式的數據,其它參數和mui.get()方法一致,使用方法: mui.get(url[,data][,success]),如上得到新聞列表的代碼換成mui.getJSON()方法後,更爲簡潔,以下:

mui.getJSON('http://server-name/list.php',{category:'news'},function(data){ //得到服務器響應 ... } );

          

手勢事件

在開發移動端的應用時,會用到不少的手勢操做,好比滑動、長按等,爲了方便開放者快速集成這些手勢,mui內置了經常使用的手勢事件,目前支持的手勢事件見以下列表:

分類 參數 描述
點擊 tap 單擊屏幕
doubletap 雙擊屏幕
長按 longtap 長按屏幕
hold 按住屏幕
release 離開屏幕
滑動 swipeleft 向左滑動
swiperight 向右滑動
swipeup 向上滑動
swipedown 向下滑動
拖動 dragstart 開始拖動
drag 拖動中
dragend 拖動結束

      

手勢事件配置

根據使用頻率,mui默認會監聽部分手勢事件,如點擊、滑動事件;爲了開發出更高性能的moble App,mui支持用戶根據實際業務需求,經過mui.init方法中的gestureConfig參數,配置具體須要監聽的手勢事件,。

mui.init({ gestureConfig:{ tap: true, //默認爲true doubletap: true, //默認爲false longtap: true, //默認爲false swipe: true, //默認爲true drag: true, //默認爲true hold:false,//默認爲false,不監聽 release:false//默認爲false,不監聽 } });

注意:dragstart、drag、dragend共用drag開關,swipeleft、swiperight、swipeup、swipedown共用swipe開關

事件監聽

同標準click事件同樣,上述手勢事件支持添加到任意DOM對象上,以下爲一個示例:

elem.addEventListener("swipeleft",function(){ console.log("你正在向左滑動"); });

        

預加載

所謂的預加載技術就是在用戶還沒有觸發頁面跳轉時,提早建立目標頁面,這樣當用戶跳轉時,就能夠當即進行頁面切換,節省建立新頁面的時間,提高app使用體驗。mui提供兩種方式實現頁面預加載。

方式一:經過mui.init方法中的preloadPages參數進行配置.

mui.init({ preloadPages:[ { url:prelaod-page-url, id:preload-page-id, styles:{},//窗口參數 extras:{},//自定義擴展參數 subpages:[{},{}]//預加載頁面的子頁面 } ] });

該種方案使用簡單、可預加載多個頁面,但不會返回預加載每一個頁面的引用,若要得到對應webview引用,還須要經過plus.webview.getWebviewById方式得到;另外,由於mui.init是異步執行,執行完mui.init方法後當即得到對應webview引用,可能會失敗,例如以下代碼:    

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

方式二:經過mui.preload方法預加載.

var page = mui.preload({ url:new-page-url, id:new-page-id,//默認使用當前頁面的url做爲id styles:{},//窗口參數 extras:{}//自定義擴展參數 });

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

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

        

下拉刷新

        爲實現下拉刷新功能,大多H5框架都是經過DIV模擬下拉回彈動畫,在低端android手機上,DIV動畫常常出現卡頓現象(特別是圖文列表的狀況);         mui經過雙webview解決這個DIV的拖動流暢度問題;拖動時,拖動的不是div,而是一個完整的webview(子webview),回彈動畫使用原生動畫;在iOS平臺,H5的動畫已經比較流暢,故依然使用H5方案。兩個平臺實現雖有差別,但mui通過封裝,可以使用一套代碼實現下拉刷新。

主頁面內容比較簡單,只須要建立子頁面便可:

mui.init({ subpages:[{ url:pullrefresh-subpage-url,//下拉刷新內容頁面地址 id:pullrefresh-subpage-id,//內容頁面標誌 styles:{ top:subpage-top-position,//內容頁面頂部位置,需根據實際頁面佈局計算,若使用標準mui導航,頂部默認爲48px; .....//其它參數定義 } }] });

內容頁面需按照以下DOM結構構建:

<!--下拉刷新容器--> <div id="refreshContainer" class="mui-content mui-scroll-wrapper"> <div class="mui-scroll"> <!--數據列表--> <ul class="mui-table-view mui-table-view-chevron"> </ul> </div> </div>

其次,經過mui.init方法中pullRefresh參數配置下拉刷新各項參數,以下:

mui.init({ pullRefresh : { container:"#refreshContainer",//下拉刷新容器標識,querySelector能定位的css選擇器都可,好比:id、.class等 down : { contentdown : "下拉能夠刷新",//可選,在下拉可刷新狀態時,下拉刷新控件上顯示的標題內容 contentover : "釋放當即刷新",//可選,在釋放可刷新狀態時,下拉刷新控件上顯示的標題內容 contentrefresh : "正在刷新...",//可選,正在刷新狀態時,下拉刷新控件上顯示的標題內容 callback :pullfresh-function //必選,刷新函數,根據具體業務來編寫,好比經過ajax從服務器獲取新數據; } } });

最後,根據具體業務編寫刷新函數,須要注意的是,加載完新數據後,須要執行endPulldownToRefresh()方法;

function pullfresh-function() { //業務邏輯代碼,好比經過ajax從服務器獲取新數據; ...... //注意,加載完新數據後,必須執行以下代碼,注意:若爲ajax請求,則需將以下代碼放置在處理完ajax響應數據以後 mui('#refreshContainer').pullRefresh().endPulldownToRefresh(); }

        

上拉加載

mui的上拉加載實現比較簡單,檢測5+ runtime提供的滾動條滾動到底事件(plusscrollbottom),顯示「正在加載」提示-->開始加載業務數據-->隱藏"正在加載"提示。使用方式相似下拉刷新,首先、經過mui.init方法中pullRefresh參數配置上拉加載各項參數,以下:

mui.init({ pullRefresh : { container:refreshContainer,//待刷新區域標識,querySelector能定位的css選擇器都可,好比:id、.class等 up : { contentrefresh : "正在加載...",//可選,正在加載狀態時,上拉加載控件上顯示的標題內容 contentnomore:'沒有更多數據了',//可選,請求完畢若沒有更多數據時顯示的提醒內容; callback :pullfresh-function //必選,刷新函數,根據具體業務來編寫,好比經過ajax從服務器獲取新數據; } } });

其次,根據具體業務編寫加載函數,須要注意的是,加載完新數據後,須要執行endPullupToRefresh()方法;

function pullfresh-function() { //業務邏輯代碼,好比經過ajax從服務器獲取新數據; ...... //注意,加載完新數據後,必須執行以下代碼,true表示沒有更多數據了,兩個注意事項: //一、若爲ajax請求,則需將以下代碼放置在處理完ajax響應數據以後 //二、注意this的做用域,若存在匿名函數,需將this複製後使用,參考hello mui中的代碼示例; this.endPullupToRefresh(true|false); }

注意:  

  • 由於使用的是滾動到底事件,所以若當前頁面內容過少,沒有滾動條的話,就不會觸發上拉加載
  • 屢次上拉加載後,若已沒有更多數據可加載時,調用this.endPullupToRefresh(true);,以後滾動條滾動到底時,將再也不顯示「上拉顯示更多」的提示語,而顯示「沒有更多數據了」的提示語;
  • 若實際業務中,有從新觸發上拉加載的需求(好比當前類別已無更多數據,但切換到另一個類別後,應支持繼續上拉加載),此時調用上拉加載的重置函數便可,以下代碼:

 

//pullup-container爲在mui.init方法中配置的pullRefresh節點中的container參數; mui('#pullup-container').pullRefresh().refresh(true);

        

輸入加強

mui目前提供的輸入加強包括:快速刪除和語音輸入兩項功能。要刪除輸入框中的內容,使用輸入法鍵盤上的刪除按鍵,只能逐個刪除字符,mui提供了快速刪除能力,只須要在對應input控件上添加.mui-input-clear類,當input控件中有內容時,右側會有一個刪除圖標,點擊會清空當前input的內容;另外,爲了方便快速輸入,mui集成了HTML5+的語音輸入,只須要在對應input控件上添加.mui-input-speech類,就會在該控件右側顯示一個語音輸入的圖標,點擊會啓用科大訊飛語音輸入界面。

        

開關事件

mui提供了開關控件樣式,點擊滑動兩種手勢均可以對開關控件進行操做,在開關控件進行切換時,會觸發toggle事件,經過事件的detail.isActive屬性能夠判斷當前開關狀態。可經過監聽toggle事件,在開關切換時執行特定業務邏輯。以下爲使用示例:

document.getElementById("mySwitch").addEventListener("toggle",function(event){ if(event.detail.isActive){ console.log("你啓動了開關"); }else{ console.log("你關閉了開關"); } })

若要得到當前開關狀態,可經過判斷當前開關控件是否包含.mui-active類來實現,若包含,則爲打開狀態,不然即爲關閉狀態;以下爲代碼示例:

var isActive = document.getElementById("mySwitch").classList.contains("mui-active"); if(isActive){ console.log("打開狀態"); }else{ console.log("關閉狀態"); }

若使用js打開、關閉開關控件,可以使用switch插件的toggle()方法,以下爲示例代碼:

mui("#mySwitch").switch().toggle();

          

slide事件

mui提供了圖片輪播、可拖動式圖文表格、可拖動式選項卡、左右滑動9宮格組件,這些組件都用到了mui框架的slide插件,有較多共同點。首先,Dom內容構造基本相同,都必須有一個.mui-slider的父容器;其次,當拖動切換顯示內容時,均會觸發slide事件(可拖動式選項卡在點擊選項卡標題時,也會觸發slide事件),經過該事件的detail.slideNumber參數能夠得到當前顯示項的索引(第一項索引爲0,第二項爲1,以此類推),利用該事件,可在顯示內容切換時,動態處理一些業務邏輯。

以下爲一個可拖動式選項卡示例,爲提升頁面加載速度,頁面加載時,僅顯示第一個選項卡的內容,第2、第三選項卡內容爲空。

<div class="mui-slider"> <!--選項卡標題區--> <div class="mui-slider-indicator mui-segmented-control mui-segmented-control-inverted"> <a class="mui-control-item" href="#item1">待辦公文</a> <a class="mui-control-item" href="#item2">已辦公文</a> <a class="mui-control-item" href="#item3">所有公文</a> </div> <div class="mui-slider-progress-bar mui-col-xs-4"></div> <div class="mui-slider-group"> <!--第一個選項卡內容區--> <div id="item1" class="mui-slider-item mui-control-content mui-active"> <ul class="mui-table-view"> <li class="mui-table-view-cell">待辦公文1</li> <li class="mui-table-view-cell">待辦公文2</li> <li class="mui-table-view-cell">待辦公文3</li> </ul> </div> <!--第二個選項卡內容區,頁面加載時爲空--> <div id="item2" class="mui-slider-item mui-control-content"></div> <!--第三個選項卡內容區,頁面加載時爲空--> <div id="item3" class="mui-slider-item mui-control-content"></div> </div> </div>

當切換到第2、第三個選項卡時,再動態獲取相應內容進行顯示:

var item2Show = false,item3Show = false;//子選項卡是否顯示標誌 document.querySelector('.mui-slider').addEventListener('slide', function(event) { if (event.detail.slideNumber === 1&&!item2Show) { //切換到第二個選項卡 //根據具體業務,動態得到第二個選項卡內容; var content = .... //顯示內容 document.getElementById("item2").innerHTML = content; //改變標誌位,下次直接顯示 item2Show = true; } else if (event.detail.slideNumber === 2&&!item3Show) { //切換到第三個選項卡 //根據具體業務,動態得到第三個選項卡內容; var content = .... //顯示內容 document.getElementById("item3").innerHTML = content; //改變標誌位,下次直接顯示 item3Show = true; } });

圖片輪播、可拖動式圖文表格等都可按照一樣方式監聽內容變化,好比咱們能夠在圖片輪播界面顯示當前正在看的是第幾張圖片:

document.querySelector('.mui-slider').addEventListener('slide', function(event) { //注意slideNumber是從0開始的; document.getElementById("info").innerText = "你正在看第"+(event.detail.slideNumber+1)+"張圖片"; });

          

自定義事件

用戶開發應用中會大量使用事件功能。除了瀏覽器內置的事件及mui框架內置的事件(好比手勢事件)外,mui同時支持用戶觸發和綁定自定義事件。經過自定義事件,用戶能夠輕鬆實現頁面間數據傳遞。

監聽自定義事件

添加自定義事件監聽操做和標準js事件監聽相似,可直接經過window對象添加,以下:

window.addEventListener('customEvent',function(event){ //經過event.detail可得到傳遞過來的參數內容 .... });

觸發自定義事件

經過mui.fire方法可觸發目標窗口的自定義事件:

mui.fire(targetPage,'customEvent',{ //自定義事件參數 });

示例:假設以下場景:重新聞列表頁面進入新聞詳情頁面,新聞詳情頁面爲共用頁面,經過傳遞新聞ID通知詳情頁面須要顯示具體哪一個新聞,詳情頁面再動態向服務器請求數據,mui要實現相似需求可經過以下步驟實現:

  •     在列表頁面中預加載詳情頁面(假設爲detail.html)  
  •     列表頁面在點擊新聞標題時,首先,得到該新聞id,觸發詳情頁面的newsId事件,並將新聞id做爲事件參數傳遞過去;而後再打開詳情頁面;  
  • 詳情頁面監聽newsId自定義事件

 

列表頁面代碼以下:

//初始化預加載詳情頁面 mui.init({ preloadPages:[{ id:'detail.html', url:'detail.html' } ] }); var detailPage = null; //添加列表項的點擊事件 mui('.mui-content').on('tap', 'a', function(e) { var id = this.getAttribute('id'); //得到詳情頁面 if(!detailPage){ detailPage = plus.webview.getWebviewById('detail.html'); } //觸發詳情頁面的newsId事件 mui.fire(detailPage,'newsId',{ id:id }); //打開詳情頁面 mui.openWindow({ id:'detail.html' }); });

詳情頁面代碼以下:

//添加newId自定義事件監聽 window.addEventListener('newsId',function(event){ //得到事件參數 var id = event.detail.id; //根據id向服務器請求新聞詳情 ..... });

      

圖片輪播

mui框架內置了圖片輪播插件,經過該插件封裝的JS API,用戶能夠設定是否自動輪播及輪播週期,以下爲代碼示例:

//得到slider插件對象 var gallery = mui('.mui-slider'); gallery.slider({ interval:5000//自動輪播週期,若爲0則不自動播放,默認爲0; });

所以若但願圖片輪播不要自動播放,而是用戶手動滑動才切換,只須要經過如上方法,將slideshowDelay參數設爲0便可。

若要跳轉到第x張圖片,則可使用圖片輪播插件的gotoItem方法,例如:

//得到slider插件對象 var gallery = mui('.mui-slider'); gallery.slider().gotoItem(index);//跳轉到第index張圖片,index從0開始;

圖片輪播涉及的另一個問題:是否支持循環播放,好比有一、二、三、4四張圖片,從第1張圖片起,依次向左滑動切換圖片,當切換到第4張圖片時,繼續向左滑動,接下來會有兩種效果:  

  • 支持循環:左滑,直接切換到第1張圖片;
  • 不支持循環:左滑,無反應,繼續顯示第4張圖片,用戶若要顯示第1張圖片,必須連續向右滑動切換到第1張圖片;

  當顯示第1張圖片時,繼續右滑是否顯示第4張圖片,是一樣問題;這個問題的實現須要經過.mui-slider-loop類及DOM節點來控制;若不支持循環,代碼比較簡單,以下:

 

<div class="mui-slider"> <div class="mui-slider-group"> <div class="mui-slider-item"><a href="#"><img src="1.jpg" /></a></div> <div class="mui-slider-item"><a href="#"><img src="2.jpg" /></a></div> <div class="mui-slider-item"><a href="#"><img src="3.jpg" /></a></div> <div class="mui-slider-item"><a href="#"><img src="4.jpg" /></a></div> </div> </div>

若要支持循環,則須要在.mui-slider-group節點上增長.mui-slider-loop類,同時須要重複增長2張圖片,圖片順序變爲:四、一、二、三、四、1,代碼示例以下:

<div class="mui-slider"> <div class="mui-slider-group mui-slider-loop"> <!--支持循環,須要重複圖片節點--> <div class="mui-slider-item mui-slider-item-duplicate"><a href="#"><img src="4.jpg" /></a></div> <div class="mui-slider-item"><a href="#"><img src="1.jpg" /></a></div> <div class="mui-slider-item"><a href="#"><img src="2.jpg" /></a></div> <div class="mui-slider-item"><a href="#"><img src="3.jpg" /></a></div> <div class="mui-slider-item"><a href="#"><img src="4.jpg" /></a></div> <!--支持循環,須要重複圖片節點--> <div class="mui-slider-item mui-slider-item-duplicate"><a href="#"><img src="1.jpg" /></a></div> </div> </div>

注意:mui框架會默認初始化當前頁面的圖片輪播組件;若輪播組件內容爲js動態生成時(好比經過ajax動態獲取的營銷信息),則須要在動態DOM生成後,手動調用圖片輪播的初始化方法;代碼以下:  

//得到slider插件對象 var gallery = mui('.mui-slider'); gallery.slider({ interval:5000//自動輪播週期,若爲0則不自動播放,默認爲0; });

      

側滑導航

mui提供了兩種側滑導航實現:webview模式和div模式,兩種模式各有優劣,適用於不一樣的場景。

webview模式

主頁面和菜單內容在不一樣的webview中,兩個頁面根據內容需求分別組織DOM結構,mui對其DOM結構無特殊要求,故其有以下優勢:

  • 菜單內容是單獨的webview,故可被多個頁面複用;
  • 菜單內容在單獨的webview中,菜單區域的滾動不影響主界面,故可以使用原生滾動,滾動更爲流暢;

另外一方面,webview模式也有其缺點:

  • 不支持拖動手勢(跟手拖動);
  • 主頁面、菜單不一樣webview實現,所以若需交互(如:點擊菜單觸發主頁面內容變化),需使用自定義事件實現跨webview通信;

div模式

    主頁面和菜單內容在同一個webview下,嵌套在特定結構的div中,經過div的移動動畫模擬菜單移動;故該模式有以下優勢:   

  • 支持拖動手勢(跟手拖動);
  • 主頁面、菜單在一個頁面中,可經過JS輕鬆實現二者交互(如:點擊菜單觸發主頁面內容變化),沒有跨webview通信的煩惱;

另外一方面,div模式也有其缺點:

  • 不支持菜單內容在多頁面的複用,需每一個頁面都生成對應的菜單節點;
  • 主界面和菜單內容的滾動互不影響,所以會使用div區域滾動,在低端Android手機且滾動內容較多時,可能會稍顯卡頓;

div模式支持不一樣的動畫效果,每種動畫效果需聽從不一樣的DOM構造;下面咱們以右滑菜單爲例(左滑菜單僅需將菜單父節點上的mui-off-canvas-left換成mui-off-canvas-right便可),說明每種動畫對應的DOM結構。

動畫1:主界面移動、菜單不動

<!-- 側滑導航根容器 --> <div class="mui-off-canvas-wrap mui-draggable"> <!-- 菜單容器 --> <aside class="mui-off-canvas-left"> <div class="mui-scroll-wrapper"> <div class="mui-scroll"> <!-- 菜單具體展現內容 --> ... <div> </div> </aside> <!-- 主頁面容器 --> <div class="mui-inner-wrap"> <!-- 主頁面標題 --> <header class="mui-bar mui-bar-nav"> <a class="mui-icon mui-action-menu mui-icon-bars mui-pull-left"></a> <h1 class="mui-title">標題</h1> </header> <div class="mui-content mui-scroll-wrapper"> <div class="mui-scroll"> <!-- 主界面具體展現內容 --> ... </div> </div> </div> </div>

動畫2:主界面不動、菜單移動  

該種動畫要求的DOM結構和動畫1的DOM結構基本相同,惟一差異就是需在側滑導航根容器class上增長一個mui-slide-in

動畫3:主界面、菜單同時移動  

該種動畫要求的DOM結構較特殊,需將菜單容器放在主頁面容器之下

<!-- 側滑導航根容器 --> <div class="mui-off-canvas-wrap mui-draggable"> <!-- 主頁面容器 --> <div class="mui-inner-wrap"> <!-- 菜單容器 --> <aside class="mui-off-canvas-left"> <div class="mui-scroll-wrapper"> <div class="mui-scroll"> <!-- 菜單具體展現內容 --> ... <div> </div> </aside> <!-- 主頁面標題 --> <header class="mui-bar mui-bar-nav"> <a class="mui-icon mui-action-menu mui-icon-bars mui-pull-left"></a> <h1 class="mui-title">標題</h1> </header> <!-- 主頁面內容容器 --> <div class="mui-content mui-scroll-wrapper"> <div class="mui-scroll"> <!-- 主界面具體展現內容 --> ... </div> </div> </div> </div>

mui支持多種方式顯示div模式的側滑菜單:一、在主界面向右拖動(drag);二、點擊含有mui-action-menu類的控件;三、Android手機按menu鍵;四、經過JS API觸發,以下:

mui('.mui-off-canvas-wrap').offCanvas('show');

一樣,mui支持多種方式關閉div模式的側滑菜單:一、在手機屏幕上任意位置向左拖動(drag);二、點擊主界面內任意位置;三、Android手機按menu鍵;四、Android手機按back鍵;五、經過JS API觸發,以下:

mui('.mui-off-canvas-wrap').offCanvas('close');

      

彈出菜單

mui框架內置了彈出菜單插件,彈出菜單顯示內容不限,但必須包裹在一個含.mui-popover類的div中,以下即爲一個彈出菜單內容:

<div id="popover" class="mui-popover"> <ul class="mui-table-view"> <li class="mui-table-view-cell"><a href="#">Item1</a></li> <li class="mui-table-view-cell"><a href="#">Item2</a></li> <li class="mui-table-view-cell"><a href="#">Item3</a></li> <li class="mui-table-view-cell"><a href="#">Item4</a></li> <li class="mui-table-view-cell"><a href="#">Item5</a></li> </ul> </div>

要顯示、隱藏如上菜單,mui推薦使用錨點方式,例如:

<a href="#popover" class="mui-btn mui-btn-primary mui-btn-block">打開彈出菜單</a>

點擊如上定義的按鈕,便可顯示彈出菜單,再次點擊彈出菜單以外的其餘區域,都可關閉彈出菜單;這種使用方式最爲簡潔。

若但願經過js的方式控制彈出菜單,則經過以下一個方法便可:

//傳入toggle參數,用戶也無需關心當前是顯示仍是隱藏狀態,mui會自動識別處理; mui('.mui-popover').popover('toggle');

        

遮罩蒙版

在popover、側滑菜單等界面,常常會用到蒙版遮罩;好比popover彈出後,除popover控件外的其它區域都會遮罩一層蒙版,用戶點擊蒙版不會觸發蒙版下方的邏輯,而會關閉popover同時關閉蒙版;再好比側滑菜單界面,菜單劃出後,除側滑菜單以外的其它區域都會遮罩一層蒙版,用戶點擊蒙版會關閉側滑菜單同時關閉蒙版。      

遮罩蒙版經常使用的操做包括:建立、顯示、關閉,以下代碼:

var mask = mui.createMask(callback);//callback爲用戶點擊蒙版時自動執行的回調; mask.show();//顯示遮罩 mask.close();//關閉遮罩

注意:關閉遮罩僅會關閉,不會銷燬;關閉以後能夠再次調用mask.show();打開遮罩;

mui默認的蒙版遮罩使用.mui-backdrop類定義(以下代碼),若需自定義遮罩效果,只需覆蓋定義.mui-backdrop便可;

.mui-backdrop { position: fixed; top: 0; right: 0; bottom: 0; left: 0; z-index: 998; background-color: rgba(0,0,0,.3); }
相關文章
相關標籤/搜索