javascript做的导航框架,MVC框架及框架单体对象A

<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8">
		<title></title>
		<script type="text/javascript" src="js/Ademo.js"></script>
		<style type="text/css">
		html,body{
			margin: 0 auto;
			padding: 0;
			font: Arial, Helvetica, sans-serif;
			font-size: 12px;
			color: black;
		}
		#slidebar{
			width: 250px;
			height: 300px;
			position: relative;
			left: 20px;
			top: 20px;
			background-color: #ccc;
		}
		.slidebar-inner{
			position: relative;
			left:60px;
			width:60px;
			height: 300px;
			background-color: white;
			color:black;
		}
		.slidebar-inner ul{
			list-style: none;
			padding: 0;
			margin: 0;
		}
		.slidebar-inner ul li{
			margin-left:10px;
			padding: 0;
			vertical-align: middle;
			width: 300px;
			height: 60px;
		}
		.box{
			vertical-align: text-bottom;
			margin-left: 60px;
			margin-top:-45px ;
			display: none;
			vertical-align: middle;
		}
		img{
			width: 35px;
			height: 35px;
		}
		
		a:link,a:visited{
			color: black;
			text-decoration: none;
		}
		a:hover{
			color:black;
			text-decoration: none;
		}
		
		</style>
	</head>
	
	<body>
		
		
		<script type="text/javascript">
		
			$(function(){
				//初始化MVC对象
				var MVC=MVC||{};
				//初始化MVC数据模型层
				MVC.model=function(){
					//内部数据对象
					var M={};
					//服务器端获取的数据,后面简化实现,直接作为同步数据写在页面中
					M.data={
						slideBar:[{
							text:'萌妹子',
							icon:'left_meng.png',
							title:'喵耳萝莉的千本樱',
							content:'自古幼女有三好~',
							img:'left_meng_img.jpeg',
							href:'http://moe.hao123.com'
						},{
							text:'动漫',
							icon:'left_comic.png',
							title:'喵耳萝莉的千本樱',
							content:'自古幼女有三好~',
							img:'left_comic_img.jpeg',
							href:'http:/v.hao123.com'
						},{
							text:'LOL直播',
							icon:'left_lol.png',
							title:'喵耳萝莉的千本樱',
							content:'自古幼女有三好~',
							img:'left_lol_img.jpeg',
							href:'http://www.hao123.com'
						},{
							text:'网络剧',
							icon:'left_tv.png',
							title:'喵耳萝莉的千本樱',
							content:'自古幼女有三好~',
							img:'left_tv_img.jpeg',
							href:'http://moe.hao123.com'
						},
						{
							text:'招贴',
							icon:'left_tie.png',
							title:'喵耳萝莉的千本樱',
							content:'自古幼女有三好~',
							img:'left_tie_img.jpeg',
							href:'http://moe.hao123.com'
						}
						
						]
					};
					//配置数据,页面加载时即提供
					M.conf={
						//侧边导航动画配置数据
						slideBarCloseAnimate:false
					};
					//返回数据模型层对象操作方法
					return{
						//获取服务器端数据
						getData:function(m){
							//根据数据字段获取数据
							return M.data[m];
						},
						//获取配置数据
						getConf:function(c){
							//根据配置数据字段获取配置数据
							return M.conf[c];
						},
						//设置服务器端数据(通常将服务器异步获取到的数据,更新该数据)
						setData:function(m,v){
							//设置数据字段m对应的数据v
							M.data[m]=v;
							return this;
						},
						//设置配置数据(通常在页面中执行某些操作,为做记录而更新配置数据)
						setConf:function(c,v){
							M.conf[c]=v;
							return this;
						}
					}
				}();
				//初始化MVC视图层
				MVC.view=function(){
					//模型数据层对象操作方法引用
					var M=MVC.model;
					//内部视图创建方法对象
					var V={
						//创建侧边导航模块视图
						createSlideBar:function(){
							//导航图标内容
							var html='';
							data=M.getData('slideBar');
							//屏蔽无效数据
							if(!data||!data.length){
								return;
							}
						//创建视图容器(Ademo.js里面的A框架)
							var dom=$.create('div',{
								'class':'slidebar',
								'id':'slidebar'
							});
						//视图容器模板
							var tpl={
								container:[
									'<div class="slidebar-inner"><ul>{#content#}</ul></div>',
									'<a hidefocus href="#" class="slidebar-close" title="收起"/>收起</a>'
								].join(''),
								//导航图标模块模板
								item:[
									'<li>',
									'<a class="icon" href="{#href#}">',
										'<img src="img/{#icon#}"/>',
										'<br>',
										'<span>{#text#}</span>',
										'</a>',
									'<div class="box">',
										'<div>',
											'<a class="title" href="{#href#}">{#title#}</a>',
											'<br>',
											'<a href="{#href#}">{#content#}</a>',
										'</div>',
										'<a class="image" href="{#href#}"><img src="img/{#img#}"/></a>',
									'</div>',
									'</li>'
								].join('')
							};
							//渲染全部导航图片模块
							for(var i=0,len=data.length;i<len;i++){
								html+=$.formateString(tpl.item,data[i]);
							}
							//在页面中创建侧边导航视图
							dom.html($.formateString(tpl.container,{content:html})).appendTo('body');
						}
					};
					//获取视图接口方法
					return function(v){
						//根据视图名称返回视图(由于获取的是一个方法,这里需要将该方法执行一遍以获取相应视图)
						V[v]();
					}
				}();
				//初始化MVC控制器层
				MVC.ctrl=function(){
					var M=MVC.model;
					var V=MVC.view;
					var C={
						//侧边导航栏模块
						initSlideBar:function(){
							V('createSlideBar');
							$('li','slidebar').on('mouseover',function(e){
							//这里跟书上有一些差别,书上不能单独弹出
								this.childNodes[1].style.display="block";
							}).on('mouseout',function(e){
								this.childNodes[1].style.display="none";
							});
							$('.slidebar-close','slidebar').on('click',function(e){
								if(M.getConf('slideBarCloseAnimate')){
									return false;
								}
								//设置侧边导航模块动画配置数据开关为打开状态
								M.setConf('slideBarCloseAnimate',true);
								//获取当前元素(就是最下面的那个隐藏箭头)
								var $this=$(this);
								//如果箭头icon是关闭状态(含有is-close类)
								if($this.hasClass('is-colse')){
									//为侧边导航模块添加显示动画
									$('.slidebar-inner','slidebar').animate({
										//动画时间
										duration:800,
										type:'easeOutQuart',
										main:function(dom){
											dom.css('left',-50+this.tween * 50 +'px');
										},
										end:function(){
											$this.removeClass('is-close');
											M.setConf('slideBarCloseAnimate',false);
										}
									});
									//如果箭头icon是打开状态(不含is-close类)
								}else{
									//为侧边导航模块添加显示动画
									$('.slidebar-inner','slidebar').animate({
										duration:800,
										type:'easeOutQuart',
										main:function(dom){
											dom.css('left',this.tween * -50 +'px');
										},
										end:function(){
											$this.addClass('is-close');
											M.setConf('slideBarCloseAnimate',false);
										}
									});
								}
							})
						}
					};
					C.initSlideBar();
				}();
			});
			
			
		</script>
		
	</body>
</html>

//这里是需要调用的Ademo.js的代码

~(function(window){
			/***
			* @name 框架单体对象A
			* @param selector选择器或页面加载回调函数
			* @param context 查找元素上下文
			***/
			var A=function(selector,context){
				//如果selector为方法则为窗口添加页面加载完成事件监听
				if(typeof selector=='function'){
					A(window).on('load',selector);
				}else{
					return new A.fn.init(selector,context);
				}
			}
			//原型方法
			A.fn=A.prototype={
				constructor:A,
				//构造函数
				init:function(selector,context){
					//modify选择器为元素
					//selector==='object'意思selector是一个数组所以为object
					if(typeof selector ==='object'){ 
						this[0]=selector;
						this.length=1;
						return this;
					}
					this.length=0,
					context=document.getElementById(context)||document;
					if(~selector.indexOf('#')){
						this[0]=document.getElementById(selector.slice(1));
						this.length=1;
					}else if(~selector.indexOf('.')){
						var doms=[],
						className=selector.slice(1);
						//支持通过类获取元素的方法
						if(context.getElementsByClassName){
							doms=context.getElementsByClassName(className);
						}else{
							doms=context.getElementsByTagName('*');
						}
						for(var i=0,len=doms.length;i<len;i++){
							if(doms[i].className&& !!~doms[i].className.indexOf(className)){
								this[this.length]=doms[i];
								this.length++;
							}
						}
						//否则为元素名选择器
					}else{
						var doms=context.getElementsByTagName(selector),i=0,
						len=doms.length;
						for(;i<len;i++){
							this[i]=doms[i];
						}
						this.length=len;
					}
					this.context=context;
					this.selector=selector;
					return this;
				},
				length:0,
				push:[].push,
				splice:[].splice
			};
			A.fn.init.prototype=A.fn;
			/***
			* @name 对象拓展
			* @param[0] 目标对象
			* @param[1,...]拓展对象
			***/
			A.extend=A.fn.extend=function(){
				var i=1,len=arguments.length,target=arguments[0],j;
				//如果参数为一个,则为当前对象拓展方法
				if(i==len){
					target=this;
					i--;
				}
				//如果参数为多个,则开始历遍拓展对象
				for(;i<len;i++){
					//遍历拓展对象中方法与属性
					for(j in arguments[i]){
						//进行浅复制
						target[j]=arguments[i][j];
					}
				}
				//返回目标对象
				return target;
			};
			A.extend({
				//将横线式命名字符转化为驼峰式
				camelCase:function(str){
					return str.replace(/\-(\w)/g,function(match,key){
						return key.toUpperCase();
					});
				},
				trim:function(str){
					return str.replace(/^\s+|\s+$/g,'');
				},
				create:function(type,value){
					var dom=document.createElement(type);
					return A(dom).attr(value);
				},
				
				formateString:function(str,data){
					var html='';
					//如果渲染数据data是数组,则遍历数组并渲染
					if(data instanceof Array){
							for(var i=0,len=data.length;i<len;i++){
							html+=arguments.callee(str,data[i]);
						}
						return html;
					}else{
						return str.replace(/\{#(\w+)#\}/g,function(match,key){
							return typeof data==='string'?data:(typeof data[key]==='undfined'?'':data[key]);
						});
					}		
				}
			});
			var _on=(function(){
				//如果标准浏览器
				if(document.addEventListener){
					return function(dom,type,fn,data){
						dom.addEventListener(type,function(e){
							fn.call(dom,e,data);
						},false);
					}
					//如果是IE浏览器
				}else if(document.attachEvent){
					return function(dom,type,fn,data){
						dom.attachEvent('on'+type,function(e){
							fn.call(dom,e,data);
						});
					}
					//如果是老浏览器
				}else{
					return function(dom,type,fn,data){
						dom['on'+type]=function(e){
							fn.call(dom,e,data);
						};
					}
				}
			})();
			A.fn.extend({
				on:function(type,fn,data){
					//这里的this就是init()里面获得元素对象的this,因为那里返回了this,所以有个数
					var i=this.length; 
					for(;--i>=0;){
						_on(this[i],type,fn,data);
					}
					return this;
				},
				//设置或者获取元素样式
				css:function(){
					var arg=arguments,len=arg.length;
					//如果无获取到的元素则返回
					if(this.length<1){
						return this;
					}
					//如果是一个参数
					if(len===1){
						//如果参数是字符串返回获取到的第一个元素样式
						if(typeof arg[0]==='string'){
							//如果是IE浏览器
							if(this[0].currentStyle){
								return this[0].currentStyle[arg[0]];
							}else{
								return getComputedStyle(this[0],false)[arg[0]];
							}
							//如果参数是一个对象,则表示是元素样式合集,读取合集内容进行设置
						}else if(typeof arg[0]==='object'){
							for(var i in arg[0]){
								for(var j=this.length-1;j>=0;j--){
									this[j].style[A.camelCase(i)]=arg[0][i];
								}
							}
						}
						//如果参数为两个字符参数,则参数2赋值于参数1
					}else if(len===2){
						for(var j=this.length-1;j>=0;j--){
							this[j].style[A.camelCase(arg[0])]=arg[1];
						}
					}
					return this;
				},
				attr:function(){
					var arg=arguments,len=arg.length;
					if(this.length<1){
						return this;
					}
					//如果是一个参数
					if(len===1){
						//如果参数是字符串则返回获取到的第一个元素的属性值
						if(typeof arg[0]==='string'){
							return this[0].getAttribute(arg[0]);
						}else if(typeof arg[0]==='object'){
							for(var i in arg[0]){
								for(var j=this.length-1;j>=0;j--){
									this[j].setAttribute(i,arg[0][i]);
								}
							}
						}
					}else if(len===2){
						for(var j=this.length-1;j>=0;j--){
							this[j].setAttribute(arg[0],arg[1]);
						}
					}
					return this;
				},
				html:function(){
					var arg=arguments,len=arg.length;
					//如果无获取到元素则返回
					if(this.length<1){
						return this;
					}
					//如果无参数则返回获取到的第一个元素内容
					if(len===0){
						return this[0].innerHTML;
						 //如果是一个参数,则设置元素等于此参数内容
					}else if(len===1){
						for(var i=this.length-1;i>=0;i--){
							this[i].innerHTML=arg[0];
						}
						//如果是两个参数或第二个参数为真,则设置元素等于此两参数的内容的连接
					}else if(len===2&&arg[1]){
						for(var i=this.length-1;i>=0;i--){
							this[i].innerHTML+=arg[0]+arg[1];
						}
					}
					return this;
				},
				appendTo:function(parent){
					var doms=A(parent);
					if(doms.length){
						for(var j=this.length-1;j>=0;j--){
							doms[0].appendChild(this[j]);
						}
					}
				},
				/***
				* @name 判断类存在
				* @param val 类名
				***/
				hasClass:function(val){
					//如果无获取到的元素则返回
					if(!this[0]){
						return;
					}
					//类名去除首尾空白符
					var value=A.trim(val);
					//如果获取到的第一个元素类名包含val则返回true,否则返回false
					return this[0].className&&this[0].className.indexOf(value)>=0?true:false;
				},
				
				/***
				* @name 添加类
				* @param val 类名
				***/
				addClass:function(val){
					var value=A.trim(val),str='';
					for(var i=0,len=this.length;i<len;i++){
						str=this[i].className;
						if(!~str.indexOf(value)){
							this[i].className+=' '+value;
						}
					}
					return this;
				},
				removeClass:function(val){
					var value=A.trim(val),
					 //将元素类名转化为数组
					classNameArr,
					//元素类名最终结果
					result; 
					for(var i=0,len=this.length;i<len;i++){
						
						if(this[i].className && ~this[i].className.indexOf(value)){
							//通过空格符将元素类名切割成数组
							classNameArr=this[i].className.split(' ');
							result='';
							for(var j=classNameArr.length-1;j>=0;j--){
								//去除类名首尾空白符
								classNameArr[j]=A.trim(classNameArr[j]);
								//如果类名存在并且类名不等于移除类,则保留该类
								result+=classNameArr[j]&&classNameArr[j]!=value?' '+classNameArr[j]:'';
							}
							this[i].className=result;
						}
					}
					return this;
				}
				
			});
			var Tween={
				//计时器句柄
				timer:0,
				//运动成员队列
				queen:[],
				//运动间隔
				interval:16,
				//缓冲函数
				easing:{
					//默认运动缓存算法匀速运动
					def:function(time,startValue,changeValue,duration){
						return changeValue*time/duration+startValue;
					},
					//缓慢结束
					easeOutQuart:function(time,startValue,changeValue,duration){
						return -changeValue*((time=time/duration-1)*time*time*time-1)+startValue;
					}
				},
				//添加运动成员
				add:function(instance){
					this.queen.push(instance);
					this.run();
				},
				//停止框架运行
				clear:function(){
					clearInterval(this.timer);
					this.timer=0;
				},
				//运行框架
				run:function(){
					if(this.timer)
					return;
					this.clear();
					this.timer=setInterval(this.loop,this.interval);
				},
				//运动框架循环方法
				loop:function(){
					if(Tween.queen.length===0){
						Tween.clear();
						return;
					}
					//获取当前时间
					var now = +new Date();
					//遍历运动成员
					for(var i=Tween.queen.length-1;i>=0;i--){
						//获取当前成员
						var instance=Tween.queen[i];
						//当前成员已运动的时间
						instance.passed=now-instance.start;
						//如果当前成员已运动的时间小于当前成员运动时间
						if(instance.passed<instance.duration){
							//执行当前成员主函数
							Tween.workFn(instance);
						}else{
							//结束当前成员运行
							Tween.endFn(instance);
						}
					}
				},
				//运行方法
				workFn:function(instance){
					//获取当前成员在当前时刻下的运动进程
					instance.tween=this.easing[instance.type](instance.passed,instance.from,instance.to=instance.from,instance.duration);
					//执行主函数
					this.exec(instance);
				},
				//结束方法
				endFn:function(instance){
					instance.passed=instance.duration;
					instance.tween=instance.to;
					this.exec(instance);
					this.distory(instance);
				},
				//执行主函数
				exec:function(instance){
					try{
						//执行当前成员主函数
						instance.main(instance.dom);
					}catch(e){}
				},
				distory:function(instance){
					//结束当前成员
					instance.end();
					//在运动成员队列中删除该成员
					this.queen.splice(this.queen.indexOf(instance),1);
					//删除成员中的每一个属性
					for(var i in instance){
						delete instance[i];
					}
				}	
			}
			/***
			* @name 获取当前成员在运动成员中的位置
			* @param instance 运动成员
			***/
			Tween.queen.indexOf=function(){
				var that=this;
				//如果有该方法则返回,如果没有则创建一个方法
				return Tween.queen.indexOf||function(instance){
					//遍历每个成员
					for(var i=0,len=that.length;i<len;i++){
						//如果该成员是需求成员则返回该成员在队列中的位置
						if(that[i]===instance){
							return i;
						}
					}
					return -1;
				}
			}();
			// A.fn对象拓展方法
			A.fn.extend({
				/***
				* @name 动画模块
				* @param obj 动画成员对象
				***/
				animate:function(obj){
					var obj=A.extend({
						duration:400,  //默认运行时间
						type:'der',  //默认动画缓存函数
						from:0,		//开始点
						to:1,		//结束点
						start: +new Date(),		//开始时间
						dom: this,	//当前元素
						main:function(){}, //运行主函数
						end:function(){}	//结束函数
					},obj);
					//向运动框架中载入运动对象成员
					Tween.add(obj);
				}	
			});
			
			A.noConflict=function(library){
				if(library){
					window.$=library;
				}else{
					window.$=null;
					delete window.$;
				}
				return A;
			}
			
			//为全局对象绑定A框架,并绑定别名$
			window.$=window.A=A;
		})(window);
		
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值