使用tree的左边菜单+多iframe实现的tab 实战

通常系统的主页面,左侧是菜单,右侧是tab按钮以及页面内容,这里给出实现的主要代码:



一:关于左侧菜单的实现:

1.1.后台java代码

1.1.1.表结构,SQL


最主要的字段就是SYS_MENU_ID:系统菜单ID,SYS_MENU_NAME:菜单名,SUP_SYS_MENU_ID:上级菜单ID。

使用mybatis查询sql语句:
<select id="querySysMenuAll"  resultMap="Result"  parameterType="com.asiainfo.psm.common.modal.SysMenu" >
	SELECT
	    B.SYS_MENU_ID AS "menu_id",
	    B.SYS_MENU_NAME AS "menu_name",
	    B.SUP_SYS_MENU_ID AS "parentid",
	    B.ORDER_SEQ  AS "orderSeq",
	    B.SYS_MODULAR_ID  AS "sysModularId"
	FROM
	    SYSTEM_MENU B
	<where>
		<if test="menu_id != null and menu_id != ''">
			AND B.SYS_MENU_ID = #{menu_id,jdbcType=INTEGER}
		</if>
	</where>    
  </select>


1.1.2.SysMenu 系统菜单实体Bean

SysMenu.java
import java.io.Serializable;

/***
 * @SysMenu 系统菜单
 * 
 * @author wlw @
 */
public class SysMenu implements Serializable {

	private static final long serialVersionUID = 1L;

	//用户ID
	private String userId;

	// 系统菜单ID
	private int menu_id;

	// 系统菜单名称
	private String menu_name;

	// 上级系统菜单ID,如果是根系统菜单,值为0
	private String parentid;

	// 展现顺序,特指同级兄弟间的展现顺序
	private String orderSeq;

	//业务模块ID
	private String sysModularId;

	//菜单级别
	private String menuflag;

	//图标链接
	private String imgurl;

	private String url;

	private String isLastNode;

	public String getUserId() {
		return userId;
	}

	public void setUserId(String userId) {
		this.userId = userId;
	}

	public int getMenu_id() {
		return menu_id;
	}

	public void setMenu_id(int menu_id) {
		this.menu_id = menu_id;
	}

	public String getMenu_name() {
		return menu_name;
	}

	public void setMenu_name(String menu_name) {
		this.menu_name = menu_name;
	}

	public String getParentid() {
		return parentid;
	}

	public void setParentid(String parentid) {
		this.parentid = parentid;
	}

	public String getMenuflag() {
		return menuflag;
	}

	public void setMenuflag(String menuflag) {
		this.menuflag = menuflag;
	}

	public String getImgurl() {
		return imgurl;
	}

	public void setImgurl(String imgurl) {
		this.imgurl = imgurl;
	}

	public String getUrl() {
		return url;
	}

	public void setUrl(String url) {
		this.url = url;
	}

	public String getIsLastNode() {
		return isLastNode;
	}

	public void setIsLastNode(String isLastNode) {
		this.isLastNode = isLastNode;
	}

	public String getOrderSeq() {
		return orderSeq;
	}

	public void setOrderSeq(String orderSeq) {
		this.orderSeq = orderSeq;
	}

	public String getSysModularId() {
		return sysModularId;
	}

	public void setSysModularId(String sysModularId) {
		this.sysModularId = sysModularId;
	}

	@Override
	public String toString() {
		return "SysMenu [menu_id=" + menu_id + ", menu_name=" + menu_name + ", parentid=" + parentid + ", menuflag="
				+ menuflag + ", imgurl=" + imgurl + ",url=" + url + "]";
	}
}


1.1.3.Node 节点类 拼接树json结构

Node.java
package com.asiainfo.psm.common.util;

import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.Iterator;
import java.util.List;

/**
 * 节点工具类
 * @author sww
 *
 */
public class Node {
	/** 
	 * 节点编号 
	 */
	public String id;

	/** 
	 * 节点内容 
	 */
	public String name;

	/** 
	 * 父节点编号 
	 */
	public String parentId;

	/** 
	 * 菜单等级
	 */
	public String menuflag;

	/**
	 * 菜单图标路径
	 */
	public String imgUrl;

	/**
	 * 路径
	 */
	public String url;

	/**
	 * 兄弟节点排序
	 */
	public String orderSeq;

	/**
	 * 业务模块ID
	 */
	public String sysModularId;

	/** 
	 * 孩子节点列表 
	 */
	private List children = new ArrayList();

	// 添加孩子节点  
	public void addChild(Node node) {
		children.add(node);
	}

	// 先序遍历,拼接JSON字符串  
	public String toString() {
		String result = "{" + "id : '" + id + "'" + ", name : '" + name + "'" + ", menuflag : '" + menuflag + "'"
				+ ", imgUrl : '" + imgUrl + "'" + ", orderSeq : '" + orderSeq + "'" + ", sysModularId : '"
				+ sysModularId + "'" + ", url : '" + url + "'";
		if (children.size() != 0) {
			result += ", submenu : [";
			for (Iterator it = children.iterator(); it.hasNext();) {
				result += ((Node) it.next()).toString() + ",";
			}
			result = result.substring(0, result.length() - 1);
			result += "]";
		} else {
			result += ", leaf : true";
		}
		return result + "}";
	}

	// 兄弟节点横向排序  
	public void sortChildren() {
		if (children.size() != 0) {
			// 对本层节点进行排序(可根据不同的排序属性,传入不同的比较器,这里传入ID比较器)  
			Collections.sort(children, new NodeIDComparator());
			// 对每个节点的下一层节点进行排序  
			for (Iterator it = children.iterator(); it.hasNext();) {
				((Node) it.next()).sortChildren();
			}
		}
	}
}

/** 
 * 节点比较器 
 */
class NodeIDComparator implements Comparator {
	// 按照节点编号比较  
	public int compare(Object o1, Object o2) {
		int j1 = Integer.parseInt(((Node) o1).id);
		int j2 = Integer.parseInt(((Node) o2).id);
		return (j1 < j2 ? -1 : (j1 == j2 ? 0 : 1));
	}
}


1.1.4.控制层处理查询菜单sql

@RequestMapping("/profile/showMenuTree.action")
	public ModelAndView showMenuTree(HttpServletRequest request) {
		ModelMap model = new ModelMap();
		//1.获取菜单list集合
		//String userId = "1";
		List<SysMenu> list = new ArrayList<SysMenu>();
		SysMenu sysMenu = new SysMenu();
		try {
			list = iSysMenuManagerBMO.querySysMenuAll(sysMenu);
		} catch (Exception e) {
			logger.error(e.getMessage() + "error");
		}

		//2.list 转成树 用的node对象集合nodeList
		HashMap nodeList = new HashMap();
		//根节点  
		Node root = null;
		HashSet<Node> hashSet = new HashSet<Node>();
		// 将结果集存入散列表(后面将借助散列表构造多叉树)  
		for (SysMenu sysmenu : list) {
			Node node = new Node();
			node.id = String.valueOf(sysmenu.getMenu_id());
			node.name = (String) sysmenu.getMenu_name();
			node.orderSeq = (String) sysmenu.getOrderSeq();
			node.sysModularId = (String) sysmenu.getSysModularId();
			String parentId = String.valueOf(sysmenu.getParentid());
			//父节点为0 置空
			if ("0".equals(parentId)) {
				node.parentId = "";
			} else {
				node.parentId = (String) sysmenu.getParentid();
			}
			nodeList.put(node.id, node);
		}

		//3.nodeList拼装json
		Set entrySet = nodeList.entrySet();
		for (Iterator it = entrySet.iterator(); it.hasNext();) {
			Node node = (Node) ((Map.Entry) it.next()).getValue();
			if (node.parentId == null || node.parentId.equals("")) {
				root = node;
			} else {
				((Node) nodeList.get(node.parentId)).addChild(node);
			}
			if (null != root) {
				hashSet.add(root);
			}
		}

		//4.对多叉树进行横向排序  
		root.sortChildren();

		//5.输出有序的树形菜单的JSON字符串   替换其中submenu 为  children
		String jsonString = String.valueOf(hashSet.toString());
		String returnString = jsonString.replaceAll("submenu", "children");
		logger.debug("输出的菜单为:" + returnString);
		model.addAttribute("returnString", returnString);
		return new ModelAndView("protected/sysMenu/sysMenuManager", model);
	}


1.2.前台js

1.2.1.common.js

//主界面左侧菜单 加载使用的js  author:sww  
function AccordionMenu(options) {
	this.config = {
		containerCls        : '.subnav',                 
		menuArrs            :  '',                         
		type                :  'click',                    
		renderCallBack      :  null,                        
		clickItemCallBack   : null                        
	};
	this.cache = {
		
	};
	this.init(options);
 }

 
 AccordionMenu.prototype = {

	constructor: AccordionMenu,

	init: function(options){
		this.config = $.extend(this.config,options || {});
		var self = this,
			_config = self.config,
			_cache = self.cache;
		
		$(_config.containerCls).each(function(index,item){
			
			self._renderHTML(item);

			self._bindEnv(item);
		});
	},
	_renderHTML: function(container){
		var self = this,
		_config = self.config,
		_cache = self.cache;
		var ulhtml;
		//检测是否IE6-8
		if (!$.support.leadingWhitespace) {
			ulhtml = $('<ul ></ul>');
		}else{			
			ulhtml = $('<ul></ul>');
		}
		$(_config.menuArrs).each(function(index,item){
			var lihtml;
			if (!$.support.leadingWhitespace) {
				lihtml = $('<li class="first-title"><a href="#" menuFlag="'+item.menuflag+'" οnclick=optMenu(this) /><h5>'+item.name+'</h5></li>');
			}else{			
				lihtml = $('<li class="first-title"><a href="#" menuFlag="'+item.menuflag+'"  οnclick=optMenu(this) /><h5>'+item.name+'</h5></li>');
			}
			if(item.submenu && item.submenu.length > 0) {
				//创建子菜单
				self._createSubMenu(item.submenu,lihtml);
			}
			$(ulhtml).append(lihtml);
		});
		$(container).append(ulhtml);
		
		_config.renderCallBack && $.isFunction(_config.renderCallBack) && _config.renderCallBack();
		
		self._levelIndent(ulhtml);
	},
	/**
	 * 创建子menu
	 * @param {array} 
	 * @param {lihtml}
	 */
	_createSubMenu: function(submenu,lihtml){
		var self = this,
			_config = self.config,
			_cache = self.cache;
		var subUl = $('<ul></ul>'),
			callee = arguments.callee,
			subLi;
		
		$(submenu).each(function(index,item){
			var url =  'javascript:void(0)';
			var menuFlag = item.menuflag; 
			var isLastNode = item.isLastNode;
			var menuUrl = item.url;
			var id = item.id;
			var imgUrl = item.imgUrl;
			//根据menuFlag 追加对应html
			if("1" == menuFlag){
				if("" != menuUrl && "null" != menuUrl){
					subLi = $('<li class="first-ss"><a id="'+id+'" targetUrl="'+menuUrl+'"  οnclick="openMenu(this)">'+item.name+'</a></li>');
				}else{
					subLi = $('<li class="first-ss"><a id="'+id+'" href="'+url+'" >'+item.name+'</a></li>');
				}
			}else if("2"  == menuFlag){ 
				//有url连接的二级菜单
				if("" != menuUrl && "null" != menuUrl){
					//二级菜单添加图标   没有则默认
					if("" != imgUrl && "null" != imgUrl){
						subLi = $('<li class="second-ss-nochild"><img src="'+imgUrl+'" height="20" width="20" class="left-ico" /><a id="'+id+'" menuFlag="'+menuFlag+'" targetUrl="'+menuUrl+'"  οnclick="openMenu(this)">'+item.name+'</a></li>');
					}else{
						subLi = $('<li class="second-ss-nochild"><img src="resources/m_images/ico2.png" height="20" width="20" class="left-ico" /><a id="'+id+'" menuFlag="'+menuFlag+'" targetUrl="'+menuUrl+'"  οnclick="openMenu(this)">'+item.name+'</a></li>');
					}
				}else{
					if("" != imgUrl && "null" != imgUrl){
						//subLi = $('<li class="second-ss"><img src="'+imgUrl+'" height="20" width="20" class="left-ico" /><a id="'+id+'" href="'+url+'" menuFlag="'+menuFlag+'"  οnclick=optMenu(this)>'+item.name+'2</a></li>');
						subLi = $('<li class="second-ss"><a id="'+id+'" href="'+url+'" menuFlag="'+menuFlag+'"  οnclick=optMenu(this)><img src="'+imgUrl+'" height="20" width="20" class="left-ico" />'+item.name+'</a></li>');
					}else{
						subLi = $('<li class="second-ss"><img src="resources/m_images/ico2.png" height="20" width="20" class="left-ico" /><a id="'+id+'" href="'+url+'" menuFlag="'+menuFlag+'"  οnclick=optMenu(this)>'+item.name+'</a></li>');
					}
				}
			}else if("3"  == menuFlag){
				if("" != menuUrl && "null" != menuUrl){
					subLi = $('<li class="third-ss"><a id="'+id+'" menuFlag="'+menuFlag+'" targetUrl="'+menuUrl+'"  οnclick="openMenu(this)"><div class="secondimg"></div>'+item.name+'</a></li>');
				}else{
					subLi = $('<li class="third-ss"><a id="'+id+'" href="'+url+'"  menuFlag="'+menuFlag+'"  οnclick=optMenu(this)><div class="secondimg"></div>'+item.name+'</a></li>');
				}
			}else{
				if("" != menuUrl && "null" != menuUrl){
					subLi = $('<li class="fourth"><a id="'+id+'"  menuFlag="'+menuFlag+'" targetUrl="'+menuUrl+'"  οnclick="openMenu(this)"'+item.name+'</a></li>');
				}else{
					subLi = $('<li class="fourth"><a id="'+id+'" href="'+url+'"  menuFlag="'+menuFlag+'"  οnclick=optMenu(this)>'+item.name+'</a></li>');
				}
			}
			if(item.submenu && item.submenu.length > 0) {

				$(subLi).children('a').prepend('<img src="resources/images/blank.gif" alt=""/>');
                callee(item.submenu, subLi);
			}
			$(subUl).append(subLi);
		});
		$(lihtml).append(subUl);
	},
	/**
	 * 
	 */
	_levelIndent: function(ulList){
			var self = this,
			_config = self.config,
			_cache = self.cache,
			callee = arguments.callee;
	   
		var initTextIndent = 2,
			lev = 1,
			$oUl = $(ulList);
		
		  while($oUl.find('ul').length > 0){
			initTextIndent = parseInt(initTextIndent,10) + 5 + 'em'; 
			$oUl.children().children('ul')
						.children('li').css("second-ss", initTextIndent);
			$oUl = $oUl.children().children('ul');
			lev++;
		 }
				
			if (!$.support.leadingWhitespace) {
				$(ulList).find('ul').slideUp();
				$(ulList).find('ul:first').slideUp();		
					//	$(ulList).find('ul').hide();
				//$(ulList).find('ul:first').hide();						
			}else{  
				$(ulList).find('ul').slideUp();
				$(ulList).find('ul:first').slideUp();				
		  }
	},
	/**
	 * 绑定事件
	 */
	_bindEnv: function(container) {
		var self = this,
			_config = self.config;

		$('h5,a',container).unbind(_config.type);
		$('h5,a',container).bind(_config.type,function(e){
			var liClass = $(this).parent().get(0).className;
			var thisLiObj = $(this).parent();
			//一级菜单伸缩样式调整
		  	  if("first-tktitle" == liClass){
				  	//收缩菜单
		  		thisLiObj.removeClass().addClass("first-title");
					  if ( !thisLiObj.is(':has(ul)') ) {
					  	  return;
					  }
				  }else if("first-title" == liClass){
				  	//打开菜单
					  thisLiObj.removeClass().addClass("first-tktitle");
					  if ( !thisLiObj.is(':has(ul)') ) {
					  	  return;
					  }
				  }	  	
			if($(this).siblings('ul').length > 0) {
				$(this).siblings('ul').slideToggle('slow').end().children('img').toggleClass('unfold');
			}
		//单击菜单时自动伸缩其他菜卿
		 //$(this).parent('li').siblings().find('ul').hide()
			 //	   .end().find('img.unfold').removeClass('unfold');
			//_config.clickItemCallBack && $.isFunction(_config.clickItemCallBack) && _config.clickItemCallBack($(this));

		});
	}
 };


function optMenu(obj){
	  slidingBox();
	  //判断当前菜单是否包含有子菜单
	  var liClass = $(obj).parent().attr("class");
	  var menuFlag = $(obj).attr("menuFlag");
	  //不同级菜单的伸缩样式改变
	  if("1" == menuFlag){ 
	  	  if("first-tktitle" == liClass){
			  	//收缩菜单
			  	 $(obj).parent().removeClass().addClass("first-title");
				  if ( !$(obj).parent().is(':has(ul)') ) {
				  	  return;
				  }else{
				  	//隐藏
				  	//$(obj).parent().find("ul").slideUp();
				  }
			  }else{
			  	//打开菜单
			  	 $(obj).parent().removeClass().addClass("first-tktitle");
				  if ( !$(obj).parent().is(':has(ul)') ) {
				  	  return;
				  }else{
				  	//隐藏
				  	//	$(obj).parent().find("ul").slideDown();
				  }
			  }	  	
	  }else if ("2" == menuFlag){
			  if("second-tk" == liClass){
			  	//收缩菜单
			  	 $(obj).parent().removeClass().addClass("second-ss");
				  if ( !$(obj).parent().is(':has(ul)') ) {
				  	  return;
				  }else{
				  	//隐藏
				  	//$(obj).parent().find("ul").slideUp();
				  }
			  }else{
			  	//打开菜单
			  	 $(obj).parent().removeClass().addClass("second-tk");
				  if ( !$(obj).parent().is(':has(ul)') ) {
				  	  return;
				  }else{
				  	//隐藏
				  	//	$(obj).parent().find("ul").slideDown();
				  }
			  }	  	
	  }else if ("3" == menuFlag){
			  if("third-tk" == liClass){
			  	//收缩菜单
			  	 $(obj).parent().removeClass().addClass("third-ss");
				  if ( !$(obj).parent().is(':has(ul)') ) {
				  	  return;
				  }else{
				  	//隐藏
				  	//$(obj).parent().find("ul").slideUp();
				  }
			  }else{
			  	//打开菜单
			  	 $(obj).parent().removeClass().addClass("third-ss");
				  if ( !$(obj).parent().is(':has(ul)') ) {
				  	  return;
				  }else{
				  	//隐藏
				  	//	$(obj).parent().find("ul").slideDown();
				  }
			  }	  
	  
	  }else if ("4" == menuFlag){
	  	
	  }
}

1.2.2.jsp中调用处

newIndex.jsp:
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<%
String path = request.getContextPath();
String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
	<base href="<%=basePath%>">
	<title>系统管理</title>
	 <link rel="stylesheet" type="text/css" href="resources/css/style.css"/>
	 <link rel="stylesheet" type="text/css" href="resources/css/m_style.css"/>
	 <script type="text/javascript" src="resources/js/jquery.min.js"></script>
	 <script type="text/javascript" src="resources/js/tabMenuEvent.js"></script>
	 <script type="text/javascript" src="resources/js/common.js"></script>
	 <script type="text/javascript">
		var ctx = '<%=request.getContextPath() %>';	 
		var loginCode = '<%=request.getAttribute("loginCode") %>';
		var isAdmin = "1";
		var timePeriod = '<%=request.getAttribute("timePeriod") %>';
		var name = '<%=request.getAttribute("name") %>';
		var userId = '<%=request.getAttribute("userId") %>';
	 </script>
	 <script type="text/javascript">
	 	var menuInfo = <%=request.getAttribute("menuObj") %>;
	 	var titleArray = new Array();
		$(function(){
			new AccordionMenu({menuArrs:menuInfo});
		});
	 </script>
	 <script type="text/javascript">
		//加载欢迎界面
	 	$(document).ready(function(){
	 		//隐藏纵向滚动条
	 		document.body.parentNode.style.overflowY = "hidden";
	 		$("#titleBegin").bind("click", function () {
	 	  		$("#cTitle").find("ul").children().removeClass("selected");
	 	  		$("#titleBegin").addClass("homeFocus");
	 		});	
	 		
	 	});  
	</script>
	 
	 
</head>
 <body>
  <div class="top">
  	<div class="top-left">
  		<img src="resources/m_images/logo.png"/>
  	</div>
  	<div class="top-right">
    	<div class="guideBar">
        	<ul><li><span class="name">${name}   您好!</span></li>
            	<li><a href="javascript:void(0)" class="icon-notice" title="消息(开发中)"><span class="dBlock">8</span></a></li>
              	<li><a href="javascript:void(0)" class="icon-setup" title="配置(开发中)"></a></li>
              	<li><a class="icon-exit" id="config" href="javascript:void(0)" title="退出" onClick="return confirmOut()" ></a></li>
        	</ul>
      	</div>
  	</div>
  </div> 
  
  <!-- tab begin-->
  <div class="cTitle" id="cTitle">
	<ul id="cTitleUl">
		<li> <a href="javascript:void(0)" class="home" id="home" targetUrl="<%=basePath%>main/profile/welcome.action" οnclick="openMenu(this)" sourcemenu="home">首页</a></li>
	</ul>
  </div>
  <!-- tab end-->
  
  <!-- 左侧菜单 -->
  <div class="sidebar">
  	<div class="nav-tt"><a href="javascript:void(0)" οnclick="onDevelop()">快捷操作</a><a href="javascript:void(0)" οnclick="onDevelop()">栏目导航</a></div>
    <div class="subnav" style="height:570px"></div>
  </div>
  
  <!-- 菜单牵引条 -->
  <div class="sul"  id="menuMove" οnclick=moveLeftDiv()><span><img id="moveImg" src="resources/images/ico9.png" height="62" width="10" /></span></div>
  
  <!-- 右侧菜单条 --> 
  <div class="con" id="toolbarId">
  </div>
	  
  <!-- 主体 -->	  
  <div class="content" id="container">
  	<iframe id="homecontentDiv" name="homecontentDiv" src="<%=basePath%>main/profile/welcome.action" width="99%" height="600px" frameborder="0" scrolling="no">
	</iframe>
  </div>
</body>
</html>


二:iframe实现tab切换

每次打开新的tab页需要创建心的iframe,并且用一个数组titleArray来保存所有创建的tab的Id,创建的每个tab的sourcemenu属性就是左侧菜单的ID。

newIndex.jsp:
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<%
String path = request.getContextPath();
String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
	<base href="<%=basePath%>">
	<title>系统管理</title>
	 <link rel="stylesheet" type="text/css" href="resources/css/style.css"/>
	 <link rel="stylesheet" type="text/css" href="resources/css/m_style.css"/>
	 <script type="text/javascript" src="resources/js/jquery.min.js"></script>
	 <script type="text/javascript" src="resources/js/tabMenuEvent.js"></script>
	 <script type="text/javascript" src="resources/js/common.js"></script>
	 <script type="text/javascript">
		var ctx = '<%=request.getContextPath() %>';	 
		var loginCode = '<%=request.getAttribute("loginCode") %>';
		var isAdmin = "1";
		var timePeriod = '<%=request.getAttribute("timePeriod") %>';
		var name = '<%=request.getAttribute("name") %>';
		var userId = '<%=request.getAttribute("userId") %>';
	 </script>
	 <script type="text/javascript">
	 	var menuInfo = <%=request.getAttribute("menuObj") %>;
	 	var titleArray = new Array();
		$(function(){
			new AccordionMenu({menuArrs:menuInfo});
		});
	 </script>
	 <script type="text/javascript">
		//加载欢迎界面
	 	$(document).ready(function(){
	 		//隐藏纵向滚动条
	 		document.body.parentNode.style.overflowY = "hidden";
	 		$("#titleBegin").bind("click", function () {
	 	  		$("#cTitle").find("ul").children().removeClass("selected");
	 	  		$("#titleBegin").addClass("homeFocus");
	 		});	
	 		
	 	});  
	</script>
	 
	 
</head>
 <body>
  <div class="top">
  	<div class="top-left">
  		<img src="resources/m_images/logo.png"/>
  	</div>
  	<div class="top-right">
    	<div class="guideBar">
        	<ul><li><span class="name">${name}   您好!</span></li>
            	<li><a href="javascript:void(0)" class="icon-notice" title="消息(开发中)"><span class="dBlock">8</span></a></li>
              	<li><a href="javascript:void(0)" class="icon-setup" title="配置(开发中)"></a></li>
              	<li><a class="icon-exit" id="config" href="javascript:void(0)" title="退出" onClick="return confirmOut()" ></a></li>
        	</ul>
      	</div>
  	</div>
  </div> 
  
  <!-- tab begin-->
  <div class="cTitle" id="cTitle">
	<ul id="cTitleUl">
		<li> <a href="javascript:void(0)" class="home" id="home" targetUrl="<%=basePath%>main/profile/welcome.action" οnclick="openMenu(this)" sourcemenu="home">首页</a></li>
	</ul>
  </div>
  <!-- tab end-->
  
  <!-- 左侧菜单 -->
  <div class="sidebar">
  	<div class="nav-tt"><a href="javascript:void(0)" οnclick="onDevelop()">快捷操作</a><a href="javascript:void(0)" οnclick="onDevelop()">栏目导航</a></div>
    <div class="subnav" style="height:570px"></div>
  </div>
  
  <!-- 菜单牵引条 -->
  <div class="sul"  id="menuMove" οnclick=moveLeftDiv()><span><img id="moveImg" src="resources/images/ico9.png" height="62" width="10" /></span></div>
  
  <!-- 右侧菜单条 --> 
  <div class="con" id="toolbarId">
  </div>
	  
  <!-- 主体 -->	  
  <div class="content" id="container">
  	<iframe id="homecontentDiv" name="homecontentDiv" src="<%=basePath%>main/profile/welcome.action" width="99%" height="600px" frameborder="0" scrolling="no">
	</iframe>
  </div>
</body>
</html>





tabMenuEvent.js
/**
 * 后台管理主框架菜单导航与快捷操作切换功能
 * @param displayId:需要显示的div Id
 * @param hiddenId:需要隐藏的div Id
 * @auther sww
 */
var tabClick = function (displayId, hiddenId){
	$("#" + displayId + "").attr("class", "block");
	$("#" + hiddenId + "").attr("class", "no");
}

/**
 * 左侧菜单点击产生tab tab点击
 * @param {Object} dom
 */
var openMenu = function(e){
	var menuId = e.id || $(e).attr("sourcemenu");
	var targetUrl = $(e).attr("targetUrl") || $(e).attr("sourceurl");
	var flag = true;
	var $menuObj = $("#" + menuId);

	if(!judugTitleAccount()){
		alert("最多只可以点击八个界面,请关闭多余界面");
		return false;
	}
	
	//titleArray tab id集合
	var flag = true;
	if(titleArray.indexOf(menuId) > -1){
		//包含元素,重定向到该元素
		flag = false;
	}else{
		titleArray.push(menuId);
	}
	
	//控制tab样式false:存在      true:不存在
	$("#titleBegin").removeClass("homeFocus");
	$.each($("#cTitleUl>li"),function(index, i){
		if($(i).children("a").text() == $menuObj.text()){
			flag = false;
			$(i).attr('class','selected');
		} else {
			$(i).attr('class','');
		}
	});
	
	//先隐藏所有的iframe的主内容
	$.each($("#container>iframe"),function(index,i){
		$(i).hide();
	})
	
	//此菜单为第一次打开,则对应在container中创建一个展示该菜单内容的iFrame,然后加载对应的页面
	if(flag && menuId != 'home'){
		if($menuObj.text() != undefined && $menuObj.text() != ''){
			$("#cTitleUl").append("<li class=\"selected\"><a href=\"javascript:void(0);\" οnclick=\"openMenu(this)\" class=\"selected\" sourcemenu=\""+menuId+"\" sourceurl=\""+targetUrl+"\">" + $menuObj.text() + "</a><b οnclick=\"closeMenuOpen('"+menuId+"')\"></b></li>");
			var childIframe = $('<iframe frameborder="0" width="100%" height="100%" scrolling="yes" name="'+ menuId+'contentDiv" id="'+ menuId+'contentDiv" src="'+targetUrl+'"></iframe>')
			childIframe.appendTo($("#container"));
		}
	} else{//如果不是第一次打开,则直接显示该div
		$("#" + menuId + "contentDiv").show();
	} 
}

/**
 * 关闭打开的类似tab页面
 * @param {Object} menuId
 */
function closeMenuOpen(menuId){
	//前一tab
	var preTab = null;
	var liNum = 0;
	$.each($("#cTitleUl>li"),function(index, i){
		liNum ++;
		if(index != 0){
			//找到当前要关闭的tab			
			if($(i).children("a").attr('sourceMenu') == menuId){
				//将tab对应的iFrame删除				
				$("#" + menuId + "contentDiv").remove();
				//将tab的ID从数组中删除
				var deleteTableIndex = titleArray.indexOf(menuId);
			  	titleArray.splice(deleteTableIndex,1);
				if($(i).attr('class')== 'selected'){//当前要关闭的页面正处于展示中状态,则删除后将其前一个tab展现
					$(preTab).attr('class','selected');
					$("#" + $(preTab).children("a").attr('sourcemenu') + "contentDiv").show();
				}
				//将tab删				
				$(i).remove();
			}
		}
		preTab = i;
	});
	//tab为2
	if(liNum == 2){
		$("#homecontentDiv",parent.document).show();
	}
}

/**
 * 从iframe界面中打开页面
 * @param {Object} targetUrl:目标url,tabName:tab名,menuId:iframe中按钮ID
 */
function openTabFromIFrame(targetUrl, tabName, menuId){
	var flag = true;//标识是否全新打开
	if(parent.titleArray.indexOf(menuId) > -1){
		//包含元素
		flag = false;
	}else{
		parent.titleArray.push(menuId);
	}
	
	
	$.each($("#cTitleUl>li", parent.document),function(index, i){
		//先隐藏所有主内容区域内容
		$("#" + $(i,parent.document).children("a").attr('sourceMenu') + 'contentDiv', parent.document).attr("style","display:none;");
		
		if(menuId != undefined && $(i,parent.document).attr('source') == menuId){
			$(i, parent.document).attr('class','selected');
			flag = false;
		}else{
			$(i, parent.document).attr('class','');
		}
	});
	
	if(!flag){//不是第一次打开,直接show
		$("#" + menuId + "contentDiv",parent.document).show();
	} else {
		//用时间戳做打开页面标识
		var timestamp = new Date().getTime(); 
		$("#cTitleUl", parent.document).append("<li class=\"selected\" source=\""+menuId+"\"><a href=\"javascript:void(0);\" οnclick=\"openTabFromIFrame('','','" + menuId + "')\" class=\"selected\" sourceMenu=\""+menuId+"\">" + tabName + "</a><b οnclick=\"closeMenuOpen('"+menuId+"')\"></b></li>");
		var childIframe = $('<iframe frameborder="0" width="100%" height="100%" scrolling="yes" name="'+ menuId+'contentDiv" id="'+ menuId+'contentDiv" src="'+targetUrl+'"></iframe>')
		childIframe.appendTo($("#container", parent.document));
	}
}

/**
 * 从iframe界面中点击关闭页面
 * @param {Object} targetTabName:调到的tab名,menuId:要关闭的tab的ID,passObject:传递的参数(可空)
 * @returns 返回的参数 returnIframeContentName(返回重新加载页面的iframe的name)
 */
function closeTabFromIFrame(targetTabName, menuId, passObject){
	
	//先隐藏所有的iframe的主内容
	$.each($("#container>iframe",parent.document),function(index,i){
		$(i).hide();
	})
	
	var deleteTableIndex = parent.titleArray.indexOf(menuId);
	parent.titleArray.splice(deleteTableIndex,1);
	
	
	//处理tab
	var returnIframeContentName;
	$.each($("#cTitleUl>li",parent.document),function(index, i){
		if($(i).children("a").text() == targetTabName){
			$(i).attr('class','selected');
			$("#" + $(i).children("a").attr('sourcemenu') + "contentDiv",parent.document).show();
			returnIframeContentName = $(i).children("a").attr('sourcemenu') + "contentDiv";
		} else {
			$(i).attr('class','');
		}
		if($(i).children("a").attr("sourceMenu") == menuId){
			//将tab删				
			$(i).remove();
		}
	});
	return returnIframeContentName;
}




点击左侧菜单调用openMenu(this)方法,在主界面newIndex.jsp创建新的iframe标签。


每次tab页的切换可以通过隐藏显示该tab对应的iframe,进行hide.show操作。


三:iframe a  下的js如何访问iframe b页面的dom元素

谷歌下本人测试

$("#tbody",document.frames('iframename').document)这种方式无效,所以可以采取折中方式,先取父页面中id=container标签,该标签包含所有iframe,然后取contents,再去找ID=tbody元素。

var $tbody = $("#container",parent.document).find("iframe[name=" + returnIframeContentName +"]").contents().find("#tbody");


附带:iframe不跨域,iframe跨域访问更加复杂不允许。







  • 0
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 5
    评论
实现一个无限级动态菜单树,可以使用 Element UI 的 Tree 组件。以下是一个简单的实现示例: 首先,需要在 Vue 中引入 Element UI 的 Tree 组件: ```javascript import { Tree } from 'element-ui'; ``` 然后,可以在 Vue 的模板中使用 `el-tree` 标签来渲染 Tree 组件: ```html <el-tree :data="menuData" :props="treeProps" @node-click="handleNodeClick"></el-tree> ``` 其中,`menuData` 是菜单数据,`treeProps` 是 Tree 组件的属性配置对象,`handleNodeClick` 是 Tree 组件的点击事件处理函数。 接下来,我们来看一下如何实现动态加载菜单数据。首先,需要在 Vue 的 `mounted` 生命周期中调用一个方法来获取菜单数据: ```javascript mounted() { this.getMenuData(); }, methods: { getMenuData() { // 通过接口获取菜单数据 } } ``` 接着,在菜单数据获取成功后,需要将数据转换成符合 Tree 组件要求的格式,并将数据保存在 Vue 实例的 `menuData` 属性中: ```javascript getMenuData() { // 通过接口获取菜单数据 // 将数据转换成符合 Tree 组件要求的格式 const menuData = convertMenuData(data); // 将数据保存在 Vue 实例的 menuData 属性中 this.menuData = menuData; } ``` 最后,我们来看一下如何处理 Tree 组件的点击事件。在 `handleNodeClick` 方法中,可以根据节点的 `level` 属性来判断当前节点是否为叶子节点。如果是叶子节点,则可以执行相应的操作,比如打开对应的页面;否则,需要递归获取子节点的数据并更新 Tree 组件的数据源: ```javascript handleNodeClick(node) { if (node.level === 2) { // 点击了叶子节点,执行相应操作 // 比如打开对应的页面 window.location.href = node.url; } else { // 点击了非叶子节点,递归获取子节点数据并更新 Tree 组件的数据源 const childNodes = await this.getChildNodes(node); node.children = childNodes; this.menuData = [...this.menuData]; } }, async getChildNodes(node) { // 通过接口获取子节点数据 const childNodesData = await getChildrenData(node.id); // 将数据转换成符合 Tree 组件要求的格式 const childNodes = convertMenuData(childNodesData); return childNodes; } ``` 至此,一个简单的无限级动态菜单树就实现了。完整的代码可以参考下面的示例: ```html <template> <el-tree :data="menuData" :props="treeProps" @node-click="handleNodeClick"></el-tree> </template> <script> import { Tree } from 'element-ui'; export default { components: { [Tree.name]: Tree }, data() { return { menuData: [], treeProps: { label: 'name', children: 'children' } }; }, mounted() { this.getMenuData(); }, methods: { async getMenuData() { // 通过接口获取菜单数据 const data = await getMenuData(); // 将数据转换成符合 Tree 组件要求的格式 const menuData = convertMenuData(data); // 将数据保存在 Vue 实例的 menuData 属性中 this.menuData = menuData; }, async handleNodeClick(node) { if (node.level === 2) { // 点击了叶子节点,执行相应操作 // 比如打开对应的页面 window.location.href = node.url; } else { // 点击了非叶子节点,递归获取子节点数据并更新 Tree 组件的数据源 const childNodes = await this.getChildNodes(node); node.children = childNodes; this.menuData = [...this.menuData]; } }, async getChildNodes(node) { // 通过接口获取子节点数据 const childNodesData = await getChildrenData(node.id); // 将数据转换成符合 Tree 组件要求的格式 const childNodes = convertMenuData(childNodesData); return childNodes; } } }; </script> ```
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值