在公司使用java ee开发的过程中,对于一些反反复复用到的web前端效果,本屌丝产生了很严重的想把他们封装好,形成各种各样的组件直接引用即可,从而减少无数次的复制粘贴的感觉。由于是自己第一次尝试封装,肯定会产生各种各样的问题。但是看着自己完成了的所谓的“作品”,自己还是觉得有点意义的。

好了,切入正题。本屌丝第一次尝试封装的是对竖直伸缩二级菜单的手风琴效果Accordion。本屌丝设计的思想并不像easyui或者bootstrap那样(即让用户引入js以及相应的css文件,在页面上定义好各式各样的div,对他们使用适当的class,就能形成相应的web前端效果)。而是采用比较笨的设计思想,也就是,首先用户需要自己在页面上定义好相应的二级菜单结构,如下代码片段:

<div id="sac2">
	<div class="slide">
		<h5>
			<a href="#">父级1</a>
		</h5>
		<ul>
			<li>
				<a href="#">菜单1-1</a>
			</li>
			<li>
				<a href="#">菜单1-2</a>
			</li>
			<li>
				<a href="#">菜单1-3</a>
			</li>
		</ul>
	</div>
	<div class="slide">
		<h5>
			<a href="#">父级2</a>
		</h5>
		<ul>
			<li>
				<a href="#">菜单2-1</a>
			</li>
			<li>
				<a href="#">菜单2-2</a>
			</li>
		</ul>
	</div>
	<div class="slide">
		<h5>
			<a href="#">父级3</a>
		</h5>
		<ul>
			<li>
				<a href="#">菜单3-1</a>
			</li>
			<li>
				<a href="#">菜单3-2</a>
			</li>
			<li>
				<a href="#">菜单3-3</a>
			</li>
		</ul>
	</div>
</div>

如上定义好html代码片段之后,这时候,只需要引入封装好的js文件,对自己想要运用的子级元素使用特效即可。必须得先引入jquery。。。(切记切记!)

在我的Accordion.js里面,你只需要在页面载入的时候写下如下简单的代码即可:

$(function() {
	var accordion1=$(".slide ul").Accordion({
		speed:"slow", 
		btnSelector:".slide h5 a"
	});
})


好了,废话不多说,下面附上所有源代码。首先是Accordion.js代码:


/*
 * 通用手风琴效果
 * @param {Object} $
 * @memberOf {TypeName} 
 * 
 * 用法:
 * 设计好页面元素之后,假设其结构为
 * 	<div>
 *  	<div class="slide">
 *       	<h5><a href="#">父级1</a></h5>
 *    	 	<ul>
 *        	 	<li><a href="#">菜单1-1</a></li>
 *        	 	<li><a href="#">菜单1-2</a></li>
 *       	 	<li><a href="#">菜单1-3</a></li>
 *     		</ul>
 *     	</div>
 *  	<div class="slide">
 *         	<h5><a href="#">父级2</a></h5>
 *     		<ul>
 *         		<li><a href="#">菜单2-1</a></li>
 *         		<li><a href="#">菜单2-2</a></li>
 *     		</ul>
 *     	</div>
 *  	<div class="slide">
 *         	<h5><a href="#">父级3</a></h5>
 *     		<ul>
 *         		<li><a href="#">菜单3-1</a></li>
 *         		<li><a href="#">菜单3-2</a></li>
 *         		<li><a href="#">菜单3-3</a></li>
 *     		</ul>
 *     	</div>
 * 	</div>
 * 那么我们只需要在页面中写如下代码
 * 	$(function(){
 * 		$(".slide ul").Accordion({
 *         speed:"slow",
 *         btnSelector:".slide h5 a"
 *      });
 * 	});
 * 其中"slow"代表手风琴效果速度,可以是毫秒数字;".slide h5 a"代表绑定父级点击伸缩事件的按钮。
 */

(function($){
	
	var Accordion=function(elemTargets,settings){
		var settings=$.extend({},Accordion.defaults,settings);
		
		//共享变量的一种方式
		//Accordion.prototype.settings=$.extend({},Accordion.defaults,settings);
		
		//实现共享变量的另一种方式,无需过多代码。原理其实和上面的一样,都是通过prototype来实现的。
		var brothers=this;
		//共享settings
		brothers.settings=settings;
		//共享需要伸缩的元素
		brothers.elemTargets=elemTargets;
		
		elemTargets.slideUp(0);
		elemTargets.eq(0).slideDown(settings.speed);
		var btnTargets=$(settings.btnSelector);
		btnTargets.each(function(n){
			$(this).click(function(){
				elemTargets.slideUp(settings.speed);
				elemTargets.eq(n).slideDown(settings.speed);
			});
		});
	}
	
	Accordion.defaults={
		speed:'normal',
		btnSelector:'.accordionBtn'
	}
	
	//对selector的元素使用手风琴效果,并返回相应的手风琴对象。如$(".slide ul").Accordion({});
	$.fn.Accordion=function(settings){
		return new Accordion(this,settings);
	}
	
	Accordion.prototype={
		/*
		 * 配合上面的Accordion.prototype.settings=$.extend({},Accordion.defaults,settings);实现共享变量
		 * @memberOf {TypeName} 
		 */
		/*
		settings:{
			speed:"slow",
			btnSelector:".accordionBtn"
		},
		*/
		
		//该方法用于刷新指定的手风琴效果对象
		refresh:function(){
			var obj=this;
			//刷新页面伸缩元素,看看是否有添加或者删除等改变
			var elemTargets=$(obj.elemTargets.selector);
			
			//共享elemTarget变量
			obj.elemTargets=elemTargets;
			
			elemTargets.slideUp(0);
			elemTargets.eq(0).slideDown(obj.settings.speed);
			var btnTargets=$(obj.settings.btnSelector);
			btnTargets.each(function(n){
				$(this).unbind('click');
				$(this).click(function(){
					elemTargets.slideUp(obj.settings.speed);
					elemTargets.eq(n).slideDown(obj.settings.speed);
				});
			});
		},
		
		//该方法用于当页面在指定手风琴对象上添加一个新元素之后的刷新
		appendOne:function(){
			var obj=this;
			
			var elemTargets=$(obj.elemTargets.selector);
			obj.elemTargets=elemTargets;
			
			elemTargets.slideUp(0);
			elemTargets.last().slideDown(obj.settings.speed);
			var btnTargets=$(obj.settings.btnSelector);
			btnTargets.each(function(n){
				$(this).unbind('click');
				$(this).click(function(){
					elemTargets.slideUp(obj.settings.speed);
					elemTargets.eq(n).slideDown(obj.settings.speed);
				});
			});
		},
		
		//该方法用于页面在指定手风琴对象上删除一个元素之后的刷新
		deleteOne:function(){
			var obj=this;
			
			var elemTargets=$(obj.elemTargets.selector);
			obj.elemTargets=elemTargets;
			
			var isOneBlock=false;
			elemTargets.each(function(){
				var $This=$(this);
				if($This.css('display')!='none') isOneBlock=true;
			});
			if(!isOneBlock) elemTargets.eq(0).slideDown(obj.settings.speed);
			var btnTargets=$(obj.settings.btnSelector);
			btnTargets.each(function(n){
				$(this).unbind('click');
				$(this).click(function(){
					elemTargets.slideUp(obj.settings.speed);
					elemTargets.eq(n).slideDown(obj.settings.speed);
				});
			});
		}
	}
	
})(jQuery);


然后就是我写的一个demo页面leftside.html


<!DOCTYPE html>
<html>
	<head>
		<title>leftside.html</title>

		<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
		<meta name="viewport" content="width=device-width,initial-scale=1.0">

		<link href="../themes/css/common.css" rel="stylesheet" type="text/css" />
		<link href="../themes/css/usercenter.css" rel="stylesheet"
			type="text/css" />
		<script type="text/javascript" src="../plugins/jquery/jquery-1.9.1.js">
</script>
		<script type="text/javascript" src="../pzControls/Accordion.js">
</script>
		<script type="text/javascript">
$(function() {
	var d1=$(".uuul span").Accordion({
		speed:400, 
		btnSelector:".uuul h5 a"
	});
	$("#aaa").click(function(){
		var divObj = $("#aaa1").clone();
		divObj.removeAttr("id");
		divObj.addClass("uuul");
		$("#aaa2").append(divObj);
		divObj.show();
		d1.appendOne();//添加一个元素之后记住要刷新一下相应的手风琴对象。手风琴对象对应的刷新方法有refresh(),appendOne(),deleteOne()
	})
	$("#aaa4").click(function(){
		$(".uuul span").last().parent().remove();
		d1.deleteOne();
	})
})

$(function() {
	var d2 = $(".slide ul").Accordion({
		btnSelector:".slide h5 a"
	});
	$("#sac").click(function(){
		var divObj = $("#sac1").clone();
		divObj.removeAttr("id");
		divObj.addClass("slide");
		$("#sac2").append(divObj);
		divObj.show();
		d2.appendOne();
	})
})
</script>
	</head>

	<body>
		<div class="leftmain-u">
			<div class="leftsidebar-middle" id="leftside">
				<div class="column" id="aaa2">
					<ul class="uuul">
						<h5>
							<a href="javascript:void(0)">方案设计</a>
						</h5>
						<span>
							<li>
								<a href="${ctx}/usercenter/ProblemTender/pageRetrieve.do"
									target="ucfrm">难题招标</a>
							</li>
							<li>
								<a href="${ctx}/usercenter/DesignOrgservice/pageRetrieve.do"
									target="ucfrm">设计机构</a>
							</li>
							<li>
								<a href="${ctx}/usercenter/DesignExpert/createOrUpdate.do"
									target="ucfrm">设计大师</a>
							</li>
							<li>
								<a href="${ctx}/usercenter/DesignTool/pageRetrieve.do"
									target="ucfrm">设计工具</a>
							</li>
							<li>
								<a href="${ctx}/usercenter/StandardTool/pageRetrieve.do"
									target="ucfrm">标准件</a>
							</li>
							<li>
								<a href="${ctx}/usercenter/DesignKnowledge/pageRetrieve.do"
									target="ucfrm">设计知识</a>
							</li>
							<li>
								<a href="${ctx}/usercenter/CreativeOutcome/pageRetrieve.do"
									target="ucfrm">创意成果</a>
							</li> 
						</span>
					</ul>
					<ul class="uuul">
						<h5>
							<a href="javascript:void(0)">软件评测</a>
						</h5>
						<span>
							<li>
								<a href="${ctx}/usercenter/EvaluationOrgservice/pageRetrieve.do"
									target="ucfrm">评测机构</a>
							</li>
							<li>
								<a href="${ctx}/usercenter/EvaluationExpert/createOrUpdate.do"
									target="ucfrm">评测人才</a>
							</li>
							<li>
								<a href="${ctx}/usercenter/EvaluationTool/pageRetrieve.do"
									target="ucfrm">评测工具</a>
							</li>
							<li>
								<a href="${ctx}/usercenter/EvaluationKnowledge/pageRetrieve.do"
									target="ucfrm">评测知识</a>
							</li>
							<li>
								<a href="${ctx}/usercenter/ClassicCase/pageRetrieve.do"
									target="ucfrm">经典案例</a>
							</li> 
						</span>
					</ul>
					<ul class="uuul">
						<h5>
							<a href="javascript:void(0)">综合检测</a>
						</h5>
						<span>
							<li>
								<a href="${ctx}/usercenter/DetectOrgservice/pageRetrieve.do"
									target="ucfrm">检测机构</a>
							</li>
							<li>
								<a href="${ctx}/usercenter/DetectExpert/createOrUpdate.do"
									target="ucfrm">检测人才</a>
							</li>
							<li>
								<a href="${ctx}/usercenter/DetectEquipment/pageRetrieve.do"
									target="ucfrm">检测设备</a>
							</li>
							<li>
								<a href="${ctx}/usercenter/DetectKnowledge/pageRetrieve.do"
									target="ucfrm">检测知识</a>
							</li>
							<li>
								<a href="${ctx}/usercenter/DetectCase/pageRetrieve.do"
									target="ucfrm">经典案例</a>
							</li> 
						</span>
					</ul>
					<ul class="uuul">
						<h5>
							<a href="javascript:void(0)">绿色制造</a>
						</h5>
						<span>
							<li>
								<a href="${ctx}/usercenter/EnergyDemand/pageRetrieve.do"
									target="ucfrm">节能需求</a>
							</li>
							<li>
								<a href="${ctx}/usercenter/EnergyOrgservice/pageRetrieve.do"
									target="ucfrm">节能机构</a>
							</li>
							<li>
								<a href="${ctx}/usercenter/EnergyExpert/createOrUpdate.do"
									target="ucfrm">节能专家</a>
							</li>
							<li>
								<a href="${ctx}/usercenter/SupportTool/pageRetrieve.do"
									target="ucfrm">节能系统</a>
							</li>
							<li>
								<a href="${ctx}/usercenter/SupportEquipment/pageRetrieve.do"
									target="ucfrm">支撑设备</a>
							</li>
							<li>
								<a href="${ctx}/usercenter/EnergyKnowledge/pageRetrieve.do"
									target="ucfrm">节能知识</a>
							</li>
							<li>
								<a href="${ctx}/usercenter/SuccessCase/pageRetrieve.do"
									target="ucfrm">成功案例</a>
							</li> 
						</span>
					</ul>
				</div>
				<input type="button" value="123123" id="aaa">
				<input type="button" value="111111" id="aaa4">
			</div>
		</div>
		<div id="sac2">
			<div class="slide">
				<h5>
					<a href="#">父级1</a>
				</h5>
				<ul>
					<li>
						<a href="#">菜单1-1</a>
					</li>
					<li>
						<a href="#">菜单1-2</a>
					</li>
					<li>
						<a href="#">菜单1-3</a>
					</li>
				</ul>
			</div>
			<div class="slide">
				<h5>
					<a href="#">父级2</a>
				</h5>
				<ul>
					<li>
						<a href="#">菜单2-1</a>
					</li>
					<li>
						<a href="#">菜单2-2</a>
					</li>
				</ul>
			</div>
			<div class="slide">
				<h5>
					<a href="#">父级3</a>
				</h5>
				<ul>
					<li>
						<a href="#">菜单3-1</a>
					</li>
					<li>
						<a href="#">菜单3-2</a>
					</li>
					<li>
						<a href="#">菜单3-3</a>
					</li>
				</ul>
			</div>
		</div>
	</body>
	<input type="button" value="123" id="sac">
	<div id="sac1" style="display: none;">
		<h5>
			<a href="#">父级n</a>
		</h5>
		<ul>
			<li>
				<a href="#">菜单n-1</a>
			</li>
			<li>
				<a href="#">菜单n-2</a>
			</li>
			<li>
				<a href="#">菜单n-3</a>
			</li>
		</ul>
	</div>

	<ul id="aaa1" style="display: none;">
		<h5>
			<a href="javascript:void(0)">方案设计</a>
		</h5>
		<span>
			<li>
				<a href="${ctx}/usercenter/ProblemTender/pageRetrieve.do"
					target="ucfrm">难题招标</a>
			</li>
			<li>
				<a href="${ctx}/usercenter/DesignOrgservice/pageRetrieve.do"
					target="ucfrm">设计机构</a>
			</li>
			<li>
				<a href="${ctx}/usercenter/DesignExpert/createOrUpdate.do"
					target="ucfrm">设计大师</a>
			</li>
			<li>
				<a href="${ctx}/usercenter/DesignTool/pageRetrieve.do"
					target="ucfrm">设计工具</a>
			</li>
			<li>
				<a href="${ctx}/usercenter/StandardTool/pageRetrieve.do"
					target="ucfrm">标准件</a>
			</li>
			<li>
				<a href="${ctx}/usercenter/DesignKnowledge/pageRetrieve.do"
					target="ucfrm">设计知识</a>
			</li>
			<li>
				<a href="${ctx}/usercenter/CreativeOutcome/pageRetrieve.do"
					target="ucfrm">创意成果</a>
			</li> 
		</span>
	</ul>
</html>


就这样,可以实现手风琴效果啦。在上面的leftside.html里面,里面涉及到的两个css文件,大伙可以忽略,没有它们并不影响我们的手风琴效果,只是我们的两个二级菜单比较丑一点而已。代码就不上传了,涉及到公司的页面设计。

在这里讲一下自己原本其实是想设计成easyui和bootstrap那样,直接在div上面应用样式就可以实现前端特效的,但是,我想到,不同的公司有不同的页面设计风格,我们不能自己写死一种样式让用户来适应我们,除非可以让用户用自己css样式文件来代替我们原本自己设计好的css样式文件,本屌丝木有什么头绪来实现这样的设计方案,如果有什么技术大神知道要怎么实现的话,欢迎想本屌丝提出,本屌丝虚心学习。

现在这样封装好之后,虽然用起来还是很麻烦,就是需要自己写二级菜单结构代码,但是效果神马的就可以交给我的Accordion.js文件来帮你实现了。所以,某种意义一常来是,还是挺灵活的。咳咳(轻喷轻喷。。。)。好啦,文章就到这里,有需要的可以复制代码下来用用试试。是基于jquery实现的,记得在引入这个js之前先引入jquery了哦。感谢耐心观看的程序员们。