现在的位置: 首页 > easyui > Layout > tabs > 正文
实现tabs组件IFrame模式的遮罩效果
2013年04月19日 tabs ⁄ 共 8244字 评论数 11 ⁄ 被围观 19,989 views+
文章目录
[隐藏]

需求分析

在jQuery Easyui框架中,大多使用url方式(即ajax方式)加载数据的话,都设计了“等待中效果”或者“遮罩效果”。但是实际应用中,并不一定只有ajax方式才需要这些效果,最常见的IFrame其实也需要这种效果,而tabs是使用IFrame频率最高的组件了,本文就来实现tabs组件IFrame模式的遮罩效果。

寻找奠基石

跟ajax不同,IFrame没有请求成功后的回调函数,要实现遮罩的话,我们必须知道在何时关闭遮罩,所以必须能够监控到IFrame是否加载完成才能做出我们想要的遮罩效果。怎样才能知道IFrame是否加载成功了呢?很幸运,我们总有巨人的肩可以站:

  1. var iframe = document.createElement("iframe");   
  2. iframe.src = "http://www.baidu.com";   
  3.   
  4. if (iframe.attachEvent){   
  5.     iframe.attachEvent("onload"function(){   
  6.         alert("Local iframe is now loaded.");   
  7.     });   
  8. else {   
  9.     iframe.onload = function(){   
  10.         alert("Local iframe is now loaded.");   
  11.     };   
  12. }   
  13. document.body.appendChild(iframe);  

如果是IE的话,我们通过attachEvent来注册onload事件,如此一来,IFrame的的onload事件就兼容各个浏览器了。

寻找一件外衣

有了奠基石,我们还得找件可以见人的衣服,遮罩效果当然要做得简洁大方又不失美观才行,我们注意到,Easyui的datagrid组件的遮罩效果就不错,实现起来也不麻烦,就是一个遮罩层,一个消息层,再用相对定位固定住绝对定位,使用top和left配合margin就能实现消息层大体水平垂直居中了。

衣服光漂亮还不行,还得性感,怎么性感呢?当然要露了,要若隐若现才性感,性感才能吸引眼球。所以,我们还需要做一个淡入淡出的效果,遮罩淡出,IFrame淡入。不幸的是,IFrame是个不听说的玩意,它总是忽略自身的z-index属性,所以我只能再用一个div容易包裹IFrame。

实现代码

  1. $(function(){   
  2.      $('#tabs').tabs({   
  3.         onAdd:function(title,index){   
  4.             var $tabBody = $('#tabs').tabs('getTab',title).panel('body');   
  5.             $tabBody.css({'overflow':'hidden','position':'relative'});   
  6.             var mask = $('<div style="position:relative;width:100%;height:100%;background:#ccc;z-index:1000;opacity:0.3;filter:alpha(opacity=30);"><div>').appendTo($tabBody);   
  7.             var maskMessage = $('<div style="width:184px;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;">Processing, please wait ...</div>').appendTo($tabBody);   
  8.             var containter = $('<div style="position:absolute;width:100%;height:100%;z-index:1;display:none"></div>').appendTo($tabBody);   
  9.   
  10.             var iframe = document.createElement("iframe");   
  11.             iframe.src = "http://www.baidu.com";   
  12.             iframe.frameBorder = 0;   
  13.             iframe.height = '100%';   
  14.             iframe.width = '100%';   
  15.             if (iframe.attachEvent){   
  16.                 iframe.attachEvent("onload"function(){   
  17.                     $([mask[0],maskMessage[0]]).fadeOut('slow',function(){   
  18.                         $(this).remove();   
  19.                         containter.fadeIn('slow');   
  20.                     });   
  21.                 });   
  22.             } else {   
  23.                 iframe.onload = function(){   
  24.                     $([mask[0],maskMessage[0]]).fadeOut('slow',function(){   
  25.                         $(this).remove();   
  26.                         containter.fadeIn('slow');   
  27.                     });   
  28.                 };   
  29.             }   
  30.             containter[0].appendChild(iframe);   
  31.         }   
  32.     });   
  33. });  

效果演示

http://www.easyui.info/easyui/demo/tabs/iframeload.html

更新日志

2013-05-15

应各位朋友提出的建议,增加updateIframeTab方法,用于刷新iframe模式的tab页,代码进行了重构,但使用方式以及参数基本没变:

  1. /**  
  2.  * @author {CaoGuangHui}  
  3.  */  
  4. $.extend($.fn.tabs.methods, {   
  5.     /**
  6.      * 加载iframe内容  
  7.      * @param  {jq Object} jq     [description]  
  8.      * @param  {Object} params    params.which:tab的标题或者index;params.iframe:iframe的相关参数  
  9.      * @return {jq Object}        [description]  
  10.      */  
  11.     loadTabIframe:function(jq,params){   
  12.         return jq.each(function(){   
  13.             var $tab = $(this).tabs('getTab',params.which);   
  14.             if($tab==nullreturn;   
  15.   
  16.             var $tabBody = $tab.panel('body');   
  17.   
  18.             //销毁已有的iframe   
  19.             var $frame=$('iframe', $tabBody);   
  20.             if($frame.length>0){   
  21.                 try{//跨域会拒绝访问,这里处理掉该异常   
  22.                     $frame[0].contentWindow.document.write('');   
  23.                     $frame[0].contentWindow.close();   
  24.                 }catch(e){   
  25.                     //Do nothing   
  26.                 }   
  27.                 $frame.remove();   
  28.                 if($.browser.msie){   
  29.                     CollectGarbage();   
  30.                 }   
  31.             }   
  32.             $tabBody.html('');   
  33.   
  34.             $tabBody.css({'overflow':'hidden','position':'relative'});   
  35.             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);   
  36.             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);   
  37.             var $containterMask = $('<div style="position:absolute;width:100%;height:100%;z-index:1;background:#fff;"></div>').appendTo($tabBody);   
  38.             var $containter = $('<div style="position:absolute;width:100%;height:100%;z-index:0;"></div>').appendTo($tabBody);   
  39.   
  40.             var iframe = document.createElement("iframe");   
  41.             iframe.src = params.iframe.src;   
  42.             iframe.frameBorder = params.iframe.frameBorder || 0;   
  43.             iframe.height = params.iframe.height || '100%';   
  44.             iframe.width = params.iframe.width || '100%';   
  45.             if (iframe.attachEvent){   
  46.                 iframe.attachEvent("onload"function(){   
  47.                     $([$mask[0],$maskMessage[0]]).fadeOut(params.iframe.delay || 'slow',function(){   
  48.                         $(this).remove();   
  49.                         if($(this).hasClass('mask-message')){   
  50.                             $containterMask.fadeOut(params.iframe.delay || 'slow',function(){   
  51.                                 $(this).remove();   
  52.                             });   
  53.                         }   
  54.                     });   
  55.                 });   
  56.             } else {   
  57.                 iframe.onload = function(){   
  58.                     $([$mask[0],$maskMessage[0]]).fadeOut(params.iframe.delay || 'slow',function(){   
  59.                         $(this).remove();   
  60.                         if($(this).hasClass('mask-message')){   
  61.                             $containterMask.fadeOut(params.iframe.delay || 'slow',function(){   
  62.                                 $(this).remove();   
  63.                             });   
  64.                         }   
  65.                     });   
  66.                 };   
  67.             }   
  68.             $containter[0].appendChild(iframe);   
  69.         });   
  70.     },   
  71.     /**
  72.      * 增加iframe模式的标签页  
  73.      * @param {[type]} jq     [description]  
  74.      * @param {[type]} params [description]  
  75.      */  
  76.     addIframeTab:function(jq,params){   
  77.         return jq.each(function(){   
  78.             if(params.tab.href){   
  79.                 delete params.tab.href;   
  80.             }   
  81.             $(this).tabs('add',params.tab);   
  82.             $(this).tabs('loadTabIframe',{'which':params.tab.title,'iframe':params.iframe});   
  83.         });   
  84.     },   
  85.     /**
  86.      * 更新tab的iframe内容  
  87.      * @param  {jq Object} jq     [description]  
  88.      * @param  {Object} params [description]  
  89.      * @return {jq Object}        [description]  
  90.      */  
  91.     updateIframeTab:function(jq,params){   
  92.         return jq.each(function(){   
  93.             params.iframe = params.iframe || {};   
  94.             if(!params.iframe.src){   
  95.                 var $tab = $(this).tabs('getTab',params.which);   
  96.                 if($tab==nullreturn;   
  97.                 var $tabBody = $tab.panel('body');   
  98.                 var $iframe = $tabBody.find('iframe');   
  99.                 if($iframe.length===0) return;   
  100.                 $.extend(params.iframe,{'src':$iframe.attr('src')});   
  101.             }   
  102.             $(this).tabs('loadTabIframe',params);   
  103.         });   
  104.     }   
  105. });  

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方法就可以了:

  1. $('#tabs').tabs('addIframeTab',{      
  2.     tab:{title:'iframe'+count++,closable:true},      
  3.     iframe:{src:'http://www.loststop.com'}      
  4. });    

目前有 11 条留言 其中:访客:8 条, 博主:3 条

  1. xshare : 2013年06月13日13:28:22  -49楼 @回复 回复

    增加的遮罩效果,感觉很好。给用户体验增分不少。


    • 管理员
      世纪之光 : 2013年06月13日14:07:05  地下1层 @回复 回复

      难得有人留言表扬下,谢谢夸奖。

      • SinMax : 2014年09月04日15:17:33  地下2层 @回复 回复

        好用啊。这样给人感觉不错。

  2. 32day : 2014年07月03日10:35:45  -48楼 @回复 回复

    非常好用!!!!

  3. iframe下如何调用啊? : 2015年01月20日14:51:44  -47楼 @回复 回复

    iframe下如何调用啊?
    parent.$(‘#tabs’).tabs(‘addIframeTab’, {
    //tab参数为一对象,其属性同于原生add方法参数 ….


    我这样写的,不行啊


    • 管理员
      世纪之光 : 2015年01月21日20:36:18  地下1层 @回复 回复

      自己调试一下吧,版本环境我一点都不知道,无法猜出原因。

      • laodushiwo : 2015年11月03日15:04:40  地下2层 @回复 回复

        你这个效果确实好,效果能出来,但总是报错Uncaught TypeError: undefined is not a function, 那个jquery.easyui.min.js里面4850行不通过,这是什么情况哈,望指教,我qq:461551789, 谢谢亲

  4. laodushiwo : 2015年11月03日15:41:42  -46楼 @回复 回复

    额,解决了,直接打开你的源代码复制进去就可以了,其实你在上面加了一个这个addEventParam,但是你上面没说明白,呵呵,恩 就这样吧,再次感谢了哈


    • 管理员
      世纪之光 : 2015年11月06日13:27:54  地下1层 @回复 回复

      有些关联性不强知识点可能会忘记写在博文里面,见谅。

  5. : 2016年04月14日17:19:21  -45楼 @回复 回复

    谢谢博主,效果能用,不过感觉很多调用还搞不懂,基础差,还不会移植。

  6. 111 : 2016年05月13日22:20:23  -44楼 @回复 回复

    怎么不设置easyui-tabs style的高宽就没效果???

给我留言

留言无头像?


×