需求分析
在jQuery Easyui框架中,大多使用url方式(即ajax方式)加載數據的話,都設計了“等待中效果”或者“遮罩效果”。但是實際應用中,並不一定只有ajax方式才需要這些效果,最常見的IFrame其實也需要這種效果,而tabs是使用IFrame頻率最高的組件了,本文就來實現tabs組件IFrame模式的遮罩效果
尋找奠基石
跟ajax不同,IFrame沒有請求成功后的回調函數,要實現遮罩的話,我們必須知道在何時關閉遮罩,所以必須能夠監控到IFrame是否加載完成才能做出我們想要的遮罩效果。怎樣才能知道IFrame是否加載成功了呢?很幸運,我們總有巨人的肩可以站:
var iframe = document.createElement("iframe");
iframe.src = "http://www.baidu.com";
if (iframe.attachEvent){
iframe.attachEvent("onload", function(){
alert("Local iframe is now loaded.");
});
} else {
iframe.onload = function(){
alert("Local iframe is now loaded.");
};
}
document.body.appendChild(iframe);
如果是IE的話,我們通過attachEvent來注冊onload事件,如此一來,IFrame的的onload事件就兼容各個瀏覽器了。
尋找一件外衣
有了奠基石,我們還得找件可以見人的衣服,遮罩效果當然要做得簡潔大方又不失美觀才行,我們注意到,Easyui的datagrid組件的遮罩效果就不錯,實現起來也不麻煩,就是一個遮罩層,一個消息層,再用相對定位固定住絕對定位,使用top和left配合margin就能實現消息層大體水平垂直居中了。
衣服光漂亮還不行,還得性感,怎么性感呢?當然要露了,要若隱若現才性感,性感才能吸引眼球。所以,我們還需要做一個淡入淡出的效果,遮罩淡出,IFrame淡入。不幸的是,IFrame是個不聽說的玩意,它總是忽略自身的z-index屬性,所以我只能再用一個div容易包裹IFrame。
實現代碼
/**
* @author {CaoGuangHui}
*/
$.extend($.fn.tabs.methods, {
/**
* 加載iframe內容
* @param {jq Object} jq [description]
* @param {Object} params params.which:tab的標題或者index;params.iframe:iframe的相關參數
* @return {jq Object} [description]
*/
loadTabIframe:function(jq,params){
return jq.each(function(){
var $tab = $(this).tabs('getTab',params.which);
if($tab==null) return;
var $tabBody = $tab.panel('body');
//銷毀已有的iframe
var $frame=$('iframe', $tabBody);
if($frame.length>0){
try{//跨域會拒絕訪問,這里處理掉該異常
$frame[0].contentWindow.document.write('');
$frame[0].contentWindow.close();
}catch(e){
//Do nothing
}
$frame.remove();
if($.browser.msie){
CollectGarbage();
}
}
$tabBody.html('');
$tabBody.css({'overflow':'hidden','position':'relative'});
var $mask = $('<div style="position:absolute;z-index:2;width:100%;height:100%;background:#ccc;z-index:1000;opacity:0.3;filter:alpha(opacity=30);"><div>').appendTo($tabBody);
var $maskMessage = $('<div class="mask-message" style="z-index:3;width:auto;height:16px;line-height:16px;position:absolute;top:50%;left:50%;margin-top:-20px;margin-left:-92px;border:2px solid #d4d4d4;padding: 12px 5px 10px 30px;background: #ffffff url(\'../../themes/default/images/loading.gif\') no-repeat scroll 5px center;">' + (params.iframe.message || 'Processing, please wait ...') + '</div>').appendTo($tabBody);
var $containterMask = $('<div style="position:absolute;width:100%;height:100%;z-index:1;background:#fff;"></div>').appendTo($tabBody);
var $containter = $('<div style="position:absolute;width:100%;height:100%;z-index:0;"></div>').appendTo($tabBody);
var iframe = document.createElement("iframe");
iframe.src = params.iframe.src;
iframe.frameBorder = params.iframe.frameBorder || 0;
iframe.height = params.iframe.height || '100%';
iframe.width = params.iframe.width || '100%';
if (iframe.attachEvent){
iframe.attachEvent("onload", function(){
$([$mask[0],$maskMessage[0]]).fadeOut(params.iframe.delay || 'slow',function(){
$(this).remove();
if($(this).hasClass('mask-message')){
$containterMask.fadeOut(params.iframe.delay || 'slow',function(){
$(this).remove();
});
}
});
});
} else {
iframe.onload = function(){
$([$mask[0],$maskMessage[0]]).fadeOut(params.iframe.delay || 'slow',function(){
$(this).remove();
if($(this).hasClass('mask-message')){
$containterMask.fadeOut(params.iframe.delay || 'slow',function(){
$(this).remove();
});
}
});
};
}
$containter[0].appendChild(iframe);
});
},
/**
* 增加iframe模式的標簽頁
* @param {[type]} jq [description]
* @param {[type]} params [description]
*/
addIframeTab:function(jq,params){
return jq.each(function(){
if(params.tab.href){
delete params.tab.href;
}
$(this).tabs('add',params.tab);
$(this).tabs('loadTabIframe',{'which':params.tab.title,'iframe':params.iframe});
});
},
/**
* 更新tab的iframe內容
* @param {jq Object} jq [description]
* @param {Object} params [description]
* @return {jq Object} [description]
*/
updateIframeTab:function(jq,params){
return jq.each(function(){
params.iframe = params.iframe || {};
if(!params.iframe.src){
var $tab = $(this).tabs('getTab',params.which);
if($tab==null) return;
var $tabBody = $tab.panel('body');
var $iframe = $tabBody.find('iframe');
if($iframe.length===0) return;
$.extend(params.iframe,{'src':$iframe.attr('src')});
}
$(this).tabs('loadTabIframe',params);
});
}
});
addIframeTab方法的參數包含以下屬性:
名稱 |
參數類型 |
描述以及默認值 |
tab |
object |
該參數是對象,其屬性列表同於tabs自帶add方法的入參屬性列表。 |
iframe.src |
string |
目標框架頁面的地址,必填項。 |
iframe.height |
string |
框架標簽iframe的高度,默認值為'100%'。 |
iframe.width |
string |
框架標簽iframe的寬度,默認值為'100%'。 |
iframe.frameBorder |
number |
框架標簽iframe的邊框寬度,默認值為0。 |
iframe.message |
string |
加載中效果顯示的消息,默認值為'Processing, please wait ...' |
updateIframeTab方法的參數包含以下屬性:
名稱 |
參數類型 |
描述以及默認值 |
which |
number/string |
tab頁的index或者標題均可以。 |
iframe |
object |
選項同於addIframeTab方法,不過可以不設置這個參數,不設置的話,則使用原有框架的src刷新。 |
使用的時候只要調用addIframeTab方法就可以了:
$('#tabs').tabs('addIframeTab',{
tab:{title:'iframe'+count++,closable:
true
},
iframe:{src:'http:
});