JavaScript设计模式系列04_组合模式写的菜单(把菜单的数据用json数组表示,降低耦合度,体现对修改关闭)

效果:

 

以下代码经过测试:

菜单的数据(json数组),文件名:menuData.js:

let menuData=[
	{
		title:"一级菜单1",
		href:"#",
		className:"oneli",
		subClassName:"two",
		children:[
			{				
				title:"二级菜单11",
				href:"#",
				className:"twoli",
				subClassName:"three",
				children:[
					{				
						title:"百度一下",
						href:"http://www.baidu.com",
						className:"threeli",
						subClassName:"",
						children:[]
					},
					{				
						title:"三级菜单112",
						href:"#",
						className:"threeli",
						subClassName:"",
						children:[]
					},
					{				
						title:"三级菜单113",
						href:"#",
						className:"threeli",
						subClassName:"",
						children:[]
					}
				]
			},
			{
				title:"二级菜单12",
				href:"#",
				className:"twoli",
				subClassName:"three",
				children:[]
			},
			{
				title:"二级菜单13",
				href:"#",
				className:"twoli",
				subClassName:"",
				children:[]
			}
		]
	},
	{
		title:"一级菜单2",
		href:"#",
		className:"oneli",
		subClassName:"two",
		children:[
			{
				title:"京东",
				href:"http://www.jd.cn",
				className:"twoli",
				subClassName:"three",
				children:[]
			}
		]
	},
	{
		title:"一级菜单3",
		href:"#",
		className:"oneli",
		subClassName:"two",
		children:[
			{	
				title:"二级菜单31",
				href:"#",
				className:"twoli",
				subClassName:"three",
				children:[
					{						
						title:"三级菜单311",
						href:"#",
						className:"threeli",
						subClassName:"",
						children:[]
					},
					{						
						title:"三级菜单312",
						href:"#",
						className:"threeli",
						subClassName:"",
						children:[]
					}
				]
			}
		]
	}
];

菜单项类,文件名:MenuItem.js

//菜单类
function MenuItem(obj){
	this.title = obj.title;//菜单上的文字
	this.href = obj.href ;//菜单对应的页面
	this.className = obj.className;//
	//this.parentMenu = obj.parentMenu;//父节点
	this.subClassName = obj.subClassName;//子菜单容器的类名
	this.children = [];//所有的子菜单
}

MenuItem.prototype.createUI = function(ulDom){
	//1、创建菜单本身的dom
	let liDom = document.createElement("li");
	liDom.className = this.className;
	let aDom = document.createElement("a");
	aDom.href = this.href;
	aDom.innerHTML = this.title;
	liDom.appendChild(aDom);
	ulDom.appendChild(liDom);
	
	//2、创建子菜单的dom
	if(this.children.length>0){
		//1)、创建子菜单的容器
		let subUlDom = document.createElement("ul");
		subUlDom.className = this.subClassName;
		liDom.appendChild(subUlDom);
		//2)、循环children,让每一个子菜单创建自身
		for(let i in this.children){
			this.children[i].createUI(subUlDom);
		}
	}	
}

MenuItem.prototype.appendChild = function(menuItem){
	this.children.push(menuItem);
}

菜单管理类,文件名:MenuManager.js


//菜单管理类
function MenuManage(menuData){
	this.menuData = menuData;
	this.children=[];//子菜单对象。
}

MenuManage.prototype.appendChild = function(menuItem){
	this.children.push(menuItem);
}

MenuManage.prototype.createUI = function(ulDom){
	//创建所有菜单的外观
	for(let i in this.children){
		this.children[i].createUI(ulDom);
	}
}

//功能:创建子菜单对象(JavaScript);
//参数:父菜单对象,子菜单数据
MenuManage.prototype.createSubMenu = function(parentMenu,menuItemObj){
	let menuItem = new MenuItem({
		title:menuItemObj.title,
		href:menuItemObj.href,
		className:menuItemObj.className,
		subClassName:menuItemObj.subClassName
	});
	parentMenu.appendChild(menuItem);
	
	for(let i in menuItemObj.children){
		this.createSubMenu(menuItem,menuItemObj.children[i]);
	}
}

MenuManage.prototype.createMenu =function(){
	//创建所有的菜单对象,并建立关系
	for(let i in this.menuData){
		this.createSubMenu(this,this.menuData[i]);
	}
}

 

html文件,菜单.html

<!DOCTYPE html>
<html>
	<head>
		<meta charset="UTF-8">
		<title></title>
		<style>
			*{ padding:0; margin:0}
			ul{ list-style:none}
			a{ text-decoration:none; display:block; width:200px; height:50px;}
			.one{ width:1000px; height:50px; line-height:50px; background:#ff0; margin:0 auto;}
			.oneli{ float:left; width:200px; height:50px; text-align:center; position:relative;}
			.oneli a:hover{ background:#0ff;}
			/*二级菜单*/
			.two{ width:200px; background:#96F; position:absolute; display:none; }
			.oneli:hover .two{ display:block;}
			.twoli a:hover{ background:#90F}
			.twoli{ position:relative;}
			/*三级菜单*/
			.three{ width:200px; background:#FF9; position:absolute; top:0px; left:200px; display:none;}
			.twoli:hover .three{ display:block;}
			.threeli a:hover{ background:#FC0}
			/*最后一个的三级菜单*/
			.last .three{ width:200px; background:#FF9; position:absolute; top:0px; left:-200px; display:none;}
			.last .twoli:hover .three{ display:block;}
			.last .threeli a:hover{ background:#FC0}
			
			</style>
	</head>
	<body>
		
		<ul id="box" class="one">
			
		</ul>
		
	</body>
</html>
<script type="text/javascript" src="js/menuData.js" ></script>
<script type="text/javascript" src="js/MenuItem.js" ></script>
<script type="text/javascript" src="js/MenuManager.js" ></script>
<script type="text/javascript">


window.onload = function(){
	//1、创建菜单管理类
	let rootMenu = new MenuManage(menuData);
	//2、建立菜单对象的关系
	rootMenu.createMenu();
	//3、创建所有的DOM元素
    rootMenu.createUI(document.getElementById("box"));
}

</script>
   

 

 

如果要看菜单的布局,请看如下代码(html文件):

 

<!DOCTYPE html>
<html>
	<head>
		<meta charset="UTF-8">
		<title></title>
		<style>
			*{ padding:0; margin:0}
			ul{ list-style:none}
			a{ text-decoration:none; display:block; width:200px; height:50px;}
			.one{ width:1000px; height:50px; line-height:50px; background:#ff0; margin:0 auto;}
			.oneli{ float:left; width:200px; height:50px; text-align:center; position:relative;}
			.oneli a:hover{ background:#0ff;}
			/*二级菜单*/
			.two{ width:200px; background:#96F; position:absolute; display:none; }
			.oneli:hover .two{ display:block;}
			.twoli a:hover{ background:#90F}
			.twoli{ position:relative;}
			/*三级菜单*/
			.three{ width:200px; background:#FF9; position:absolute; top:0px; left:200px; display:none;}
			.twoli:hover .three{ display:block;}
			.threeli a:hover{ background:#FC0}
			/*最后一个的三级菜单*/
			.last .three{ width:200px; background:#FF9; position:absolute; top:0px; left:-200px; display:none;}
			.last .twoli:hover .three{ display:block;}
			.last .threeli a:hover{ background:#FC0}
			
			</style>
	</head>
	<body>
		<ul id="box" class="one">
			<li class="oneli">
				<a href="#">一级菜单1</a>
				<ul class="two">
					<li class="twoli">
						<a href="#">二级菜单11</a>
						<ul class="three">
							<li class="threeli">
								<a href="http://www.baidu.com">进入百度一下</a>
								
							</li>
							<li class="threeli">
								<a href="#">三级菜单112</a>
							</li>
							<li class="threeli">
								<a href="#">三级菜单113</a>
							</li>
						</ul>
					</li>
					<li class="twoli">
						<a href="#">二级菜单12</a>						
					</li>
					<li class="twoli">
						<a href="#">二级菜单13</a>
					</li>
				</ul>
			</li>
			<li class="oneli">
				<a href="#">一级菜单2</a>
				<ul class="two">
					<li class="twoli">
						<a href="#">二级菜单21</a>
					</li>
					<li class="twoli">
						<a href="#">二级菜单22</a>
					</li>
					<li class="twoli">
						<a href="#">二级菜单23</a>
					</li>
				</ul>
			</li>
			<li class="oneli">
				<a href="#">一级菜单3</a>
				<ul class="two">
					<li class="twoli">
						<a href="#">二级菜单31</a>
					</li>
					<li class="twoli">
						<a href="#">二级菜单32</a>
					</li>
					<li class="twoli">
						<a href="#">二级菜单33</a>
					</li>
				</ul>
			</li>
		</ul>
	</body>
</html>
<script type="text/javascript">

</script>
   

 

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值