1. 程式人生 > >jQuery Easy UI 實現頁面的Loading效果(類似於Android的ProgressDialog)

jQuery Easy UI 實現頁面的Loading效果(類似於Android的ProgressDialog)

前言

很常用的一種前端效果,比如當用戶點選網頁的某個按鈕傳送了一條非同步請求,如果響應時間過長容易導致使用者重複點選,一方面影響使用者體驗一方面容易造成不必要的服務端壓力,Easy UI有現成的mask樣式,簡單封裝一下就可以使用,之前查閱蒐集了相關資料和文章,發現都介紹的都不是很完整,所以本篇blog就完整的記錄一下通過Easy UI快速實現這種效果以及如何整合到專案中。

引入、封裝和呼叫

首先當然是在我們的專案中整合jquery以及easyui的相關資源包,除了jquery的核心js檔案,easyui的話一般也不需要完整的包,除了核心js檔案之外根據需求保留部分即可,我在專案中的目錄檔案是:


接下來就是在jsp頁面中引入js和css了:

<!-- jquery core -->
<script type="text/javascript" src="${pageContext.request.contextPath}/js/jquery/jquery-1.8.0.min.js"></script>
<!-- easyui -->
<link rel="stylesheet" type="text/css" href="${pageContext.request.contextPath}/js/easyui/themes/default/easyui.css">
<script type="text/javascript" src="${pageContext.request.contextPath}/js/easyui/jquery.easyui.min.js"></script>
<script language="javascript"  src="${pageContext.request.contextPath}/js/easyui/locale/easyui-lang-zh_CN.js"></script>

接下來就是核心的js程式碼了,新建一個common.js,將mask的樣式以及操作封裝成一個MaskUtil物件:
var MaskUtil = (function(){  
    
    var $mask,$maskMsg;  
      
    var defMsg = '正在處理,請稍待。。。';  
      
    function init(){  
        if(!$mask){  
            $mask = $("<div class=\"datagrid-mask mymask\"></div>").appendTo("body");  
        }  
        if(!$maskMsg){  
            $maskMsg = $("<div class=\"datagrid-mask-msg mymask\">"+defMsg+"</div>")  
                .appendTo("body").css({'font-size':'12px'});
        }  
          
        $mask.css({width:"100%",height:$(document).height()});  
          
        $maskMsg.css({  
            left:($(document.body).outerWidth(true) - 190) / 2,top:($(window).height() - 45) / 2,
        });   
                  
    }  
      
    return {  
        mask:function(msg){  
            init();  
            $mask.show();  
            $maskMsg.html(msg||defMsg).show();  
        }  
        ,unmask:function(){  
            $mask.hide();  
            $maskMsg.hide();  
        }  
    }  
      
}());  

可以看到,在初始化時,我們定義了2個div,第一個div設定了easyui的datagrid-mask樣式,即通過設定整個頁面的透明度來達到“遮蔽”的那種效果,在easyui.css可以找到這個樣式:
.datagrid-mask {
  position: absolute;
  left: 0;
  top: 0;
  width: 100%;
  height: 100%;
  opacity: 0.3;
  filter: alpha(opacity=30);
  display: none;
}
而第二個div設定了datagrid-mask-msg樣式,即是我們居中的小dialog窗體,並通過一行文字來進行提示,同樣的看看它的css樣式:
.datagrid-mask-msg {
  position: absolute;
  top: 50%;
  margin-top: -20px;
  padding: 12px 5px 10px 30px;
  width: auto;
  height: 16px;
  border-width: 2px;
  border-style: solid;
  display: none;
}

可以看到我們封裝的這個MaskUtil物件提供了2個方法:mask和unmask,顯而易見,一個顯示Loding,另一個是隱藏Loading,這樣只要我們在頁面引入了common.js,我們就可以方便的呼叫這兩個方法來實現Loding效果了。

關於如何呼叫想必大家都已經很清楚了,我們都會選擇在耗時任務開始的時候開啟mask,當得到服務端響應的時候結束mask,完全類似於Android中的處理方式,比如我們在Activity中new一個ProgressDialog,一般在工作執行緒開啟或者AsynTask execute時show dialog,而當非同步任務結束時會在onPostExecute方法中再呼叫dialog.dismiss().

在web中依然是類似的,我們可以在$.ajax方法之前呼叫MaskUtil.mask()去開啟Loding,而在ajax的success或者error的回撥方法中再呼叫MaskUtil.unmask()來隱藏Loding,比如我在專案中就是這樣寫的:

function getExportExcel2() {
	MaskUtil.mask();
	$.ajax({
		url : '../../app/studentInfo/getExportStudentInfoExcelTwo',
		method : 'post',
		cache : false,
		success : function(data) {
			MaskUtil.unmask();
			if ("ok" == data.data) {
				if (confirm("匯出成功,是否立即下載?")) {
					var fileName = data.fileName;
					window.location.href = "../../filedown/" + fileName
							+ ".zip";
				}
			}
		}
	});
}

是不是一目瞭然,我覺得不用做過多說明了,最後看一下效果圖:


當點選“匯出Excel”按鈕即可看到上圖效果,當服務端響應成功之後Loding效果會自動取消。但仔細和Android的ProgressDialog比較一下不難發現少了一個動態的圓形進度條,Android中的ProgressDialog作為一個標準的UI控制元件是自帶圓形進度條的,它通過setTitle和setMessage來設定Loding的標題和內容,而easyui的mask其實也是自帶這種效果的,但是需要一張gif圖片,我們只需要把loading.gif這張圖片拷貝到easyui的themes-default-images目錄下即可,這張gif圖可以在下載好的easyui包中找到,即這樣一張圖:


將這張圖拷貝到上面說的目錄之後,清理一下瀏覽器快取,重新整理頁面,再次點選“匯出Excel”按鈕,即可看到如下的效果圖:


這次就可以完美的看到我們的Loading效果了。

總結

本篇blog記錄了web中Loading的一種較為簡單和常用的解決方案,核心js檔案來自網路,我僅僅做了部分分析並且和Android中的ProgressDialog做了比較,以後我也會把專案中遇到的比較好的功能總結一下寫到blog中,邊學習邊總結,邊總結邊積累,哪怕只有一點點也是進步。加油,Raito!