轉:http://my.oschina.net/u/2331760/blog/391937?fromerr=saqeoxxB
jQuery Easyui 的tabs插件有兩種方式加載某個tab(標簽頁)上的內容:“href遠程請求”和“content本地內容”,本文就兩種方式的優缺點進行簡單分析和思考。
- 兩者特點:
- href方式加載數據的特點:
- content方式加載數據的特點:
- 簡單總結:
- href常見問題:
- 1.href只加載目標URL的html片段
- 2.短暫的頁面混亂:
- 3.html片段的easyui組件相關腳本莫名地報錯:
- 4.放在window里面表單驗證的提示信息會亂串:
- 5.兩次或者多次加載遠程數據問題:
兩者特點:
href方式加載數據的特點:
-
被加載的頁面只有body元素內部的內容才會被加載,也就是jQuery的ajax請求的只是html片段。
-
加載遠程url時有遮罩效果,也就是“等待中……”效果,用戶體驗較好。
-
當加載的頁面布局較為復雜,或者有較多的js腳本需要運行的時候,編碼往往就需要謹慎了,容易出問題,后面會詳細談。
content方式加載數據的特點:
-
比較靈活,你可以在腳本里面拼寫html代碼,然后賦值給tab的content屬性,不過這種寫法會使得代碼易讀性變差。
-
可以把iframe賦給content,把一個iframe嵌入也就沒有什么不能完成的了。
-
使用iframe會造成客戶端js重復加載,浪費資源,比如說你主頁面要引用easyui的庫,你的iframe也要引用,浪費就產生了。
簡單總結:
根據上面的分析,使用content的方式較為簡潔,而且可以引入iframe來搞定一切,缺點也很明顯,系統較為復雜的話,將帶來極大地資源浪費,只適合較為簡單的頁面系統;
而href方式則對編碼能力要求的稍微高一些,因為html的片段,稍微不注意就會處理不好,不過熟練的話,個人覺得href方式是不二之選。
href常見問題:
1.href只加載目標URL的html片段
這個特性是由jQuery封裝的ajax請求處理機制所決定的,所以目標URL頁面里不需要有html,head,body等標簽,即使有這些元素,也會被忽略,所以放在head標簽里面的任何腳本也不會被引入或者執行。
2.短暫的頁面混亂:
href鏈接的頁面比較復雜的時候,easyui對其渲染往往需要一個較長的過程,這時候,加載進來的html片段毫無布局可以,過一會自動會好,這時候easyui已經完成對它的渲染。如何避免這個混亂的過程呢,還得靠easyui的一個基礎插件——解析器(Parser)。
Parser有個onComplete事件,這個事件就是指easyui對頁面完成渲染時觸發,這樣思路就很清晰了:用一個div遮罩住讓被加載進來的html片段,在onComplete事件中,讓這個div淡出,這時候渲染好的html片段就能美人出浴了,同時還整了個等待中的效果,一舉兩得。這樣要做兩件事:
第一是在要加載的html片段中放一個遮罩用的div:
<div id=
"loading"
style=
"position: absolute; z-index: 1000; top: 0px; left: 0px; width: 100%; height: 100%; background: #DDDDDB; text-align: center; padding-top: 20%;"
></div>
第二是在被加載的html片段尾部處理相關事件:
function
show(){
$(
"#loading"
).fadeOut(
"normal"
,
function
(){
$(
this
).remove();
});
}
var
delayTime;
$.parser.onComplete =
function
(){
if
(delayTime)
clearTimeout(delayTime);
delayTime = setTimeout(show,500);
}
需要注意的是,如果多個tab頁面都使用了onComplete事件,當前定義的會覆蓋之前定義的。其實每次easyui渲染完成均會調用onComplete事件,所以每打開一個包含easyui控件的tab頁,onComplete事件就會被調用。
3.html片段的easyui組件相關腳本莫名地報錯:
其實這個現象是跟第一個現象的原因一樣的,easyui完成對html片段渲染需要一定的時間,頁面越復雜,耗時越長,這時候難以避免html存在的腳本存在對easyui某些插件的調用,比如datagrid等,這個時候就會報錯,解決方案同上,將這些腳本放到onComplete事件里處理,也就保證了渲染完成前,不會被執行。
4.放在window里面表單驗證的提示信息會亂串:
這個現象應該是插件自身的bug,對位置的計算沒有考慮到這些特殊的事情,解決方式可以投機取巧,在打開window后,讓表單不符合驗證的input獲得焦點就可以了。
5.兩次或者多次加載遠程數據問題:
官方已經說明在1.2.5的版本中已經修正了這個Bug,但是還是有不少人反應會出現兩次加載遠程數據的現象,甚至在1.2.6版本中也會遇到,如果您確實遇到這種情況了,請按以下方式檢查:
-
遠程數據返回的數據中是否包含class=”easyui-tabs”或者class=”easyui-datagrid”這樣的樣式了, 如果有的話,easyui在獲取html片段后會自動渲染,這時候已經對遠程數據源做了一次請求;
-
您是否又用javascript去$(‘#tabsId’).tabs({…});或者$(‘#tabsId’).datagrid({…});去綁定事件或者設置屬性,其實等於又一次渲染了對應控件,會再次請求遠程數據。
為什么會這樣,看看源碼便知道了:
$.fn.tabs =
function
(options, param){
if
(
typeof
options ==
'string'
) {
//這個地方的分支很清楚,只有當options為字符串的時候,才是直接調用控件本身提供的方法。
return
$.fn.tabs.methods[options](
this
, param);
}
//如果options不是字符串,直接構造控件,inxing渲染。
options = options || {};
return
this
.each(
function
(){
var
state = $.data(
this
,
'tabs'
);
var
opts;
if
(state) {
opts = $.extend(state.options, options);
state.options = opts;
}
else
{
$.data(
this
,
'tabs'
, {
options: $.extend({}, $.fn.tabs.defaults, $.fn.tabs.parseOptions(
this
), options),
tabs: wrapTabs(
this
),
selectHis: []
});
}
buildButton(
this
);
setProperties(
this
);
setSize(
this
);
initSelectTab(
this
);
});
};