DWZ中navTab使用解析

这几天老师让我看一下DWZ,看了一下给的文档,发现是一头雾水,只讲了怎么用,但是却不知道它是怎么个流程来实现的,于是便自己对着demo看了一下具体的实现过程,下面给大家分析一下。

先贴一下我仿照demo写的一个小例子的代码。

<body>
    <div id="leftside">          <!-- 左边的div用来存储树状的菜单结构 -->
        <div id="sidebar">
            <div id="toggleCollapse"><h2>主菜单</h2><span>收缩</span></div>
            <div class="accordion" fillSpace="sidebar">
                <div class="accordionHeader">
                    <h2><span>Folder</span>界面组件</h2>
                </div>
                <div class="accordionContent"> 
                    <ul class="tree treeFolder">
                        <li><a href="liuwei.html" target="navTab">主面板框架</a>
                            <ul>
                                <li><a href="liuwei.html" target="navTab" rel="liuwei">刘伟页面</a></li>
                                <li><a href="ningqin.html" target="navTab" rel="ningqin">宁琴页面</a></li>
                            </ul>
                        </li>
                    </ul>
                </div>
            </div>
        </div>
    </div>
    <div id="container">
        <div id="navTab" class="tabsPage">
            <div class="tabsPageHeader">           <!-- 右边容器头部应该包含tab标签 -->
                <div tabsPageHeaderContent>
                    <ul class="navTab-tab">
                        <!-- 开始的时候并没有标签 -->
                    </ul>
                </div>
                <div class="tabsLeft">left</div>
                <div class="tabsRight">right</div>
                <div class="tabsMore">more</div>
            </div>
            <ul class="tabsMoreList">              <!-- 点击更多时,应该会显示 这个链表-->
            </ul>
            <div class="navTab-panel tabsPageContent layoutBox">
                <div class="page unitBox">
                </div>
            </div>
        </div>
    </div>
</body>
DWZ号称只需要我们写html文件,尽量不需要我们写js代码(一个合格的程序员不会写js代码岂不可笑)。所以他给的我们那些demo, 尽是一些html文件,却没有相应的响应属性的声明(onclick属性)。这是我们就可能会疑惑了,没有事件声明 怎么来处理事件呢? 实质上,他是有响应事件的声明,只不过,它把这些事件的声明通过js代码来执行。比如说看demo中的

如下代码:

$(function(){
	DWZ.init("dwz.frag.xml", {
		loginUrl:"login_dialog.html", loginTitle:"登录",	// 弹出登录对话框
//		loginUrl:"login.html",	// 跳到登录页面
		statusCode:{ok:200, error:300, timeout:301}, //[可选]
		pageInfo:{pageNum:"pageNum", numPerPage:"numPerPage", orderField:"orderField", orderDirection:"orderDirection"}, //[可选]
		keys: {statusCode:"statusCode", message:"message"}, //[可选]
		ui:{hideMode:'offsets'}, //[可选]hideMode:navTab组件切换的隐藏方式,支持的值有’display’,
		                         //’offsets’负数偏移位置的值,默认值为’display’
		debug:false,	// 调试模式 [true|false]
		callback:function(){
			initEnv();
			$("#themeList").theme({themeBase:"themes"}); // themeBase 相对于index页面的主题base路径
		}
	});
});
这里定义了一个自执行函数,也就是文档加载完的时候会自动执行的函数,在这个函数中有一个回调函数,里面有调用initEnv()方法。在这个initEnv方法中有对各种元素组件的响应事件的声明。其中initEnv()函数的声明在dwz.ui.js文件中,下面是initEnv()方法的源码:

function initEnv() {
	$("body").append(DWZ.frag["dwzFrag"]);

	$(window).resize(function(){
		initLayout();
		$(this).trigger(DWZ.eventType.resizeGrid);
	});

	var ajaxbg = $("#background,#progressBar");
	ajaxbg.hide();
	$(document).ajaxStart(function(){
		ajaxbg.show();
	}).ajaxStop(function(){
		ajaxbg.hide();
	});
	
	if ($.fn.jBar) $("#leftside").jBar({minW:150, maxW:700});
	
	if ($.taskBar) $.taskBar.init();
	if ($.fn.switchEnv) $("#switchEnvBox").switchEnv();
	if ($.fn.navMenu) $("#navMenu").navMenu();
		
	setTimeout(function(){
		initLayout();
		if (window.navTab) 
			navTab.init();

		// 注册DWZ插件。
		DWZ.regPlugins.push(initUI); //第三方jQuery插件注册方法:DWZ.regPlugins.push(function($p){});

		// 首次初始化插件
		$(document).initUI();        //在initUI中有对各种插件的初始化,例如navTab啥的
		
		// navTab styles
		var jTabsPH = $("div.tabsPageHeader");
		jTabsPH.find(".tabsLeft").hoverClass("tabsLeftHover");
		jTabsPH.find(".tabsRight").hoverClass("tabsRightHover");
		jTabsPH.find(".tabsMore").hoverClass("tabsMoreHover");

		$(document).trigger(DWZ.eventType.initEnvAfter);
	}, 10);
}
在这个方法中,有指明在文档加载完之后的延迟指定对插件的初始化,也就是使得当前网页调用initUI()方法。在initUI()方法中有对各种存在的插件的初始化,其中对<a target="natTab">的初始化代码如下:

// navTab
$("a[target=navTab]", $p).each(function(){                                                 //从这里开始的,对于每一个target=navTab的<a>
	$(this).click(function(event){
		var $this = $(this);                                                               //得到<a>
		var title = $this.attr("title") || $this.text();
		var tabid = $this.attr("rel") || "_blank";                                         //默认_blank或者指定为rel
		var fresh = eval($this.attr("fresh") || "true");                                   //是否要刷新
		var external = eval($this.attr("external") || "false");
		var url = unescape($this.attr("href")).replaceTmById($(event.target).parents(".unitBox:first"));
		DWZ.debug(url);
		if (!url.isFinishedTm()) {
			alertMsg.error($this.attr("warn") || DWZ.msg("alertSelectMsg"));
			return false;
		}
		navTab.openTab(tabid, url,{title:title, fresh:fresh, external:external});          //调用navTab对象中的方法

		event.preventDefault();
	});
});
在这个代码中,接受了从<a>标签传过来的各种信息,包括需要打开的url地址,以及新打开的tab的id。接着他就会去调用dwz.natTab.js文件中的navTab对象的openTab()方法来打开相应的url地址。我们接着去看dwz.natTab.js中的一些代码。先着重了解一下navTab的定义的变量和init()方法,下面是源码:
var navTab = {                                                                          //navTab对象,在其他文件中可直接调用里面的方法
	componentBox: null, // tab component. contain tabBox, prevBut, nextBut, panelBox
	_tabBox: null,
	_prevBut: null,
	_nextBut: null,
	_panelBox: null,
	_moreBut:null,
	_moreBox:null,
	_currentIndex: 0,
	
	_op: {id:"navTab", stTabBox:".navTab-tab", stPanelBox:".navTab-panel", mainTabId:"main",
          close$:"a.close", prevClass:"tabsLeft", nextClass:"tabsRight", stMore:".tabsMore", stMoreLi:"ul.tabsMoreList"},
	
	init: function(options){
		if ($.History) $.History.init("#container");
		var $this = this;
		$.extend(this._op, options);

		this.componentBox = $("#"+this._op.id);                                                 //找到id为navTab的容器
		this._tabBox = this.componentBox.find(this._op.stTabBox);                               //在这个容器中寻找class为navTab-tab的容器
		this._panelBox = this.componentBox.find(this._op.stPanelBox);                           //在这个容器中寻找class为navTab-panel的容器
		this._prevBut = this.componentBox.find("."+this._op.prevClass);                         //找到左边的那个tab标签
		this._nextBut = this.componentBox.find("."+this._op.nextClass);                         //找到右边的那个标签
		this._moreBut = this.componentBox.find(this._op.stMore);                                //找到class为tabsMore的元素
		this._moreBox = this.componentBox.find(this._op.stMoreLi);                              //找到ul.tabsMoreList标签,也就是显示更多

		this._prevBut.click(function(event) {$this._scrollPrev()});
		this._nextBut.click(function(event) {$this._scrollNext()});
		this._moreBut.click(function(){
			$this._moreBox.show();
			return false;
		});
		$(document).click(function(){$this._moreBox.hide()});
		
		this._contextmenu(this._tabBox);
		this._contextmenu(this._getTabs());
		
		this._init();
		this._ctrlScrollBut();
	},
	未完,下面还有其他方法
}

在这个方法中它定义了为某个div重新载入相应的url链接页面所需要的参数。比如说实现显示各种tab的tab链表及相应的内容的panel 的容器,以及显示tab链表的容器,显示tab对应的文本内容的容器,然后在init()方法中对这些 需要的参数进行的初始化赋值。注意, 上面这些初始化赋值都是通过选择器来根据class类别来找到相应的容器来实现的,所以我们在用dwz的时候,一定要保证和上面_op变量中那些class名保持一致,不然的话,就无法使用dwz。你可以看我贴出的demo代码,里面的各种容器名字和_op变量中保持一致。比如class="navTab-tab",class="navTab-panel"等等等等,说白了,我们用dwz,就是根据它的一些约束,来帮我们实现一些js代码来实现的功能,所以才号称我们不用写js代码。

最后我们再看一下openTab()方法,其源码如下:

openTab: function(tabid, url, options){           //if found tabid replace tab, else create a new tab.
	var op = $.extend({title:"New Tab", type:"GET", data:{}, fresh:true, external:false}, options);     //用于合并对象

	var iOpenIndex = this._indexTabId(tabid);     

	if (iOpenIndex >= 0){                                                                               //如果这个tab已经存在
		var $tab = this._getTabs().eq(iOpenIndex);                                                      //找到natTab-tab下对应的那个<li>标签
		var span$ = $tab.attr("tabid") == this._op.mainTabId ? "> span > span" : "> span";              //找到<li>标签的tabid属性对应的tabid名
		$tab.find(">a").attr("title", op.title).find(span$).html(op.title);
		var $panel = this._getPanels().eq(iOpenIndex);                                                  //找到navTab-panel下对应的div
		if(url && (op.fresh || $tab.attr("url") != url)) {
			$tab.attr("url", url);
			if (op.external || url.isExternalUrl()) {
				$tab.addClass("external");
				navTab.openExternal(url, $panel);
			} else {
				$tab.removeClass("external");
				$panel.ajaxUrl({
					type:op.type, url:url, data:op.data, callback:function(){
						navTab._loadUrlCallback($panel);                                                //向那个div中重新载入信息
					}
				});
			}
		}
		this._currentIndex = iOpenIndex;
	} else {                                     //如果不存在,则直接新建一个,需要在navTab-tab中新建一个<li>标签,
                                                 //以及在navTab-panel中新加一个div
		var tabFrag = '<li tabid="#tabid#"><a href="javascript:" title="#title#" class="#tabid#"><span>#title#</span></a>
		              <a href="javascript:;" class="close">close</a></li>';
		this._tabBox.append(tabFrag.replaceAll("#tabid#", tabid).replaceAll("#title#", op.title));
		this._panelBox.append('<div class="page unitBox"></div>');
		this._moreBox.append('<li><a href="javascript:" title="#title#">#title#</a></li>'.replaceAll("#title#", op.title));
			
		var $tabs = this._getTabs();
		var $tab = $tabs.filter(":last");
		var $panel = this._getPanels().filter(":last");

		if(url) {
			if (op.external || url.isExternalUrl()) {
				$tab.addClass("external");
				navTab.openExternal(url, $panel);
			} else {
				$tab.removeClass("external");
				$panel.ajaxUrl({
					type: op.type, url: url, data: op.data, callback: function () {
						navTab._loadUrlCallback($panel);                                               //也是重新载入信息
					}
				});
			}
		}
			
		if ($.History) {
			setTimeout(function(){
				$.History.addHistory(tabid, function(tabid){
					var i = navTab._indexTabId(tabid);
					if (i >= 0) navTab._switchTab(i);
				}, tabid);
			}, 10);
		}
				
		this._currentIndex = $tabs.size() - 1;
		this._contextmenu($tabs.filter(":last").hoverClass("hover"));
	}
		
	this._init();
	this._scrollCurrent();
		
	this._getTabs().eq(this._currentIndex).attr("url", url);
}

这样就实现了通过点击相应的tab来重新载入相应的内容。

  • 4
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值