标签:
在探讨C/S模式的Tab之前,我们先总结一下B/S模式的Tab通常是什么样的。web中常见的tab设计通常是用于分节展示大量信息以提高页面空间的利用率,而且这些信息通常是静态的,或者交互比较简单。通过ajax动态加载tab内容的技术也是为这种应用场景设计的。
随着Web技术的发展,越来越多的桌面应用都在向Web应用转型。在这个过程中,很多C/S模式的应用场景不可避免的会被移植到Web中。但是B/S模式相对较弱的交互性决定了某些移植很难实现或者效果不好。C/S模式的Tab设计就是其中之一。
所谓C/S模式的Tab实际上是为了在不需要打开多个应用的情况下,可以同时对多个对象进行操作,以提高工作效率。这个应用场景在往B/S移植的过程中,如果沿用B/S常用的tab技术,通过ajax动态加载tab内容,就会有一些技术难点:
其实解决上面这些问题的方式是很多的。经过一些尝试、失败和总结,我选择了一种现代结合复古的方式:动态生成iframe,并通过iframe的src属性来区分不同的tab。采用这种方案之后,上面难题都迎刃而解,唯一的不足就是tab子页和主页间的交互会变得比较复杂。请猛击这里看demo。这个demo模拟了一个查看、修改订单的应用场景,主要实现了这些功能:
下面我们就一步一步的实现上面的功能。
这个demo用到了jquery和jquery的ui库,文件结构如图:
其中:
由于篇幅的限制,这里就不贴代码了,demo的源代码在文章最后可以下载。
现在我们可以开始编写index.js了。首先是初始化tab:
// 初始化tab $( "#tabs" ).tabs({ tabTemplate: ‘<li><a href="#{href}">#{label}</a><a class="close" href="#">x</a></li>‘, cache: true }) .bind( "tabsadd", function( event, ui ) { $( this ).tabs( "select", "#" + ui.panel.id ); });
初始化参数中的tabTemplate是为后面的关闭tab做准备。这里还绑定了一个tabsadd的事件处理函数,作用是在添加tab之后立即选中新增的tab。
如果现在打开页面,只能看到订单列表一个tab,下面我们让列表中的连接被点击之后,添加一个新tab显示对应订单的详情:
// 点击添加tab页 $( ".list a" ).click( function( e ) { e.preventDefault(); var href = $( this ).attr( "href" ); var orderid = href.substring( href.indexOf( "-" ) + 1 ); var tabid = "order-" + orderid; var url = "order.php?orderid=" + orderid; var label = "订单详情-" + orderid; addTab( tabid, url, label ); }); // 添加tab的接口 function addTab( id, url, label ) { var mainTab = $( "#tabs" ); var panel = $( "<div/>" ).attr({ "id": id }).appendTo( mainTab ); mainTab.tabs( "add", "#" + id, label ); $( "<iframe/>" ).attr({ "frameBorder": "0", "scrolling": "no", "allowTransparency": "true", "src": url }).css({ "width": "100%", "height": "100px" }).load( function() { var iframe = $( this ); iframe.height( iframe.contents().find( "body" ).height()); }).appendTo( panel ); }
上面的代码中,我们编写了一个方法作为添加tab的通用接口。在点击某一个订单链接的时候,我们会调用这个添加tab的接口,按顺序做这几件事:
现在如果多次点击订单列表中的同一个链接,我们会打开多个相同的tab。为了避免这种情况发生,我们需要在添加tab之前,通过iframe的src判断这个tab是否已经被打开,如果已经被打开,则选中这个tab(4行至15行):
// 添加tab的接口 function addTab( id, url, label ) { var mainTab = $( "#tabs" ); var added = false; $( "iframe", mainTab ).each( function( i ) { var src = this.src.substring( this.src.lastIndexOf( "/" ) + 1 ); if ( src == url ) { added = $( this ); } }); if ( added ) { mainTab.tabs( "select", "#" + added.parent().attr( "id" )); return; } var panel = $( "<div/>" ).attr({ "id": id }).appendTo( mainTab ); mainTab.tabs( "add", "#" + id, label ); $( "<iframe/>" ).attr({ "frameBorder": "0", "scrolling": "no", "allowTransparency": "true", "src": url }).css({ "width": "100%", "height": "100px" }).load( function() { var iframe = $( this ); iframe.height( iframe.contents().find( "body" ).height()); }).appendTo( panel ); }
最后我们让tab上的关闭链接发挥作用。实现这个功能通常的思路是,在每次添加tab的时候(tabsadd事件)绑定关闭tab的处理函数。但是这里我们会使用jquery 1.3中的一个新特性——live event来实现这个功能:
// 动态绑定关闭tab的事件 $( ".ui-tabs-nav a.close" ).live( "click", function( e ) { e.preventDefault(); var index = $( ".ui-tabs-nav li" ).index( $( this ).parent()); $( "#tabs" ).tabs( "remove", index ); });
简单的说,live event就是预先给某些目前DOM中可能不存在,但是未来会被动态加入到DOM中的元素绑定事件处理函数。想了解更多关于live event的信息,请参考jquery的文档。
至此,demo中的所有功能我们都已经实现了。这种实现C/S模式tab的方案,就目前来说,我觉得不是完美的,但却是可行性最强的。现实的开发中可能出现的一些其他常用需求,比如加载iframe的loading效果,实现起来都会比较容易。
标签:
原文地址:http://www.cnblogs.com/longhs/p/4529477.html