JS面向对象之编写组件小实例——实现选项卡,放大镜和照片墙-张柏沛IT博客

正文内容

JS面向对象之编写组件小实例——实现选项卡,放大镜和照片墙

栏目:Web前端 发布时间:2019-12-14 09:59 浏览量:181

下面实例的源码和材料可以从下面的链接获取:

链接:https://pan.baidu.com/s/1Ijv6OlpF5PrUWI15PLBSwg 
提取码:slij 
 

 

1.用JQ写一个选项卡组件,这个选项卡组件有两个配置选择(一个是点击触发切换还是鼠标移入触发切换、一个是有没有延迟,延迟只有在鼠标移入切换的时候才有效),3种方法(获取选项卡中内容、选择初始的active的选项卡,自动播放方法),两种自定义事件(切换前要干的事和切换后要干的事)


<html>
	<head>
	<script src="jquery.js"></script>
	<style>
		#d1 div,#d2 div,#d3 div,#d4 div{
			width:200px;
			height:200px;
			border:1px solid black;
			display:none;
		}
		.active{
			background:red;
		}
	</style>
	<script>
	$(function(){
		var t1=new Tab();
		t1.init("d1");
		
		var t2=new Tab();
		t2.init("d2");
		t2.autoPlay();
		
		var t3=new Tab();
		t3.init("d3",{event:"mouseover",delay:500});
		t3.autoPlay();
		
		var t4=new Tab();
		t4.init("d4",{event:"mouseover",delay:300});
		$(t4).on("beforeChange",function(){
			alert(t4.getContent());
		});
		$(t4).on("afterChange",function(){
			alert(t4.getContent());
		});
	});
	
	function Tab(id){
		this.oTab=null;
		this.aInput=null;
		this.aDiv=null;
		this.iNow=0;
		this.timer=null;
		this.playTimer=null;
		this.isPlay=false;
		
		this.settings={
			event:"click",    //默认触发切换事件是点击
			delay:0			  //延迟时间
		};
	}
	
	Tab.prototype.init=function(id,opt){
		this.oTab=$("#"+id);
		this.aInput=this.oTab.find(".tab-btn");
		this.aDiv=this.oTab.find(".tab-box");
		
		//更换配置参数
		$.extend(this.settings,opt);
		console.log(this.settings);
		
		var _this=this;
		this.aInput.on(this.settings.event,function(){
			_this.delayChange($(this));
			
		}).on("mouseout",function(){
			clearTimeout(_this.timer);
		});
	}
	
	Tab.prototype.delayChange=function(btn){
		var _this=this;
		
		//判断是否有延迟
		if(this.settings.event == "mouseover" && this.settings.delay>0){
		//alert(213);
			this.timer=setTimeout(function(){_this.change(btn)},this.settings.delay);
		}else{
			this.change(btn);
		}
	}
	
	Tab.prototype.change=function(btn){
		$(this).trigger("beforeChange");
		this.aInput.removeClass("active");
		this.aDiv.hide();
		
		btn.addClass("active");
		this.aDiv.eq(btn.index()).show();
		this.iNow=btn.index();
		if(this.isPlay){
			clearInterval(this.playTimer);
			this.autoPlay();
		}
		$(this).trigger("afterChange");
	}
	
	Tab.prototype.initActive=function(i){
		if(i==-1){
			i = this.aInput.length-1;
		}
	
		this.aInput.removeClass("active");
		this.aDiv.hide();
		
		this.aInput.eq(i).addClass("active");
		this.aDiv.eq(i).show();
		this.iNow=i;
	}
	
	Tab.prototype.getContent=function(){
		return this.aDiv.eq(this.iNow).html();
	}
	
	Tab.prototype.autoPlay=function(){
		this.isPlay=true;
		var _this=this;
		this.playTimer=setInterval(function(){
			var i=(_this.iNow==_this.aInput.length-1)?0:_this.iNow+1;
			var btn=_this.aInput.eq(i);
			_this.change(btn);
		},1500);
	}
		
	</script>
	</head>
	<body>
		<div id="d1">
			
			<input class="tab-btn active" type="button" value="1">
			<input class="tab-btn" type="button" value="2" >
			<input class="tab-btn" type="button" value="3" >
			
			<div class="tab-box" style="display:block">111</div>
			<div class="tab-box">222</div>
			<div class="tab-box">333</div>
		</div>
		
		<div id="d2">
			
			<input class="tab-btn active" type="button" value="1" class="active">
			<input class="tab-btn" type="button" value="2" >
			<input class="tab-btn" type="button" value="3" >
			
			<div class="tab-box" style="display:block">111</div>
			<div class="tab-box">222</div>
			<div class="tab-box">333</div>
		</div>
		
		<div id="d3">
			
			<input class="tab-btn active" type="button" value="1" class="active">
			<input class="tab-btn" type="button" value="2" >
			<input class="tab-btn" type="button" value="3" >
			
			<div class="tab-box" style="display:block">111</div>
			<div class="tab-box">222</div>
			<div class="tab-box">333</div>
		</div>
		
		<div id="d4">
			
			<input class="tab-btn active" type="button" value="1" class="active">
			<input class="tab-btn" type="button" value="2" >
			<input class="tab-btn" type="button" value="3" >
			
			<div class="tab-box" style="display:block">111</div>
			<div class="tab-box">222</div>
			<div class="tab-box">333</div>
		</div>
	</body>
</html>


用js写面向对象的时候,有几点要注意:
1.给this.settings覆盖opt的时候,可以使用jq的$.extend(),效果和我之前在js封装的extend()函数是一样的;
2.在添加自定义事件的时候,不需要再自己定义bindEvent和fireEvent函数,直接使用jq的on方法就能定义自定义事件,触发的时候使用trigger()才能触发自定义事件,因为自定义事件要手动触发
2.在给普通对象定义自定义事件的时候,要在对象外套一层$(),如上面的$(t4).on(...) 以及 $(t4).trigger();

 

2.面向过程开发放大镜
在这里有一个问题,子集影响父级,比如

<html>
	<head>
	<script src="jquery.js"></script>
	<style>
		#d1{
			width:200px;
			height:200px;
			background:red;
			
		}
		#d2{
			width:100px;
			height:100px;
			background:yellow;
			
		}
		
	</style>
	<script>
		$(function(){
			var d1=$("#d1");
			var d2=$("#d2");
			
			d1.mouseover(function(){
				document.title+="in";
			}).mouseout(function(){
				document.title+="out";
			});
		});
	</script>
	</head>
	<body>
		<div id="d1">
			<div id="d2">
			</div>
		</div>
	</body>
</html>

 


鼠标从红的移到黄的上面,会同时出现out和in
说明同时出发了mouseover和mouseout
原因:移入黄的时候,会触发红的mouseout,然后鼠标移入会冒泡到红的色块,所以又触发了红的mouseover

这个问题出现在放大镜中,结果是在移动的时候,放大镜色块会闪来闪去,就是因为不停的触发红色块的mouseover和mouseout事件;

解决方法就是:用onmouseenter和onmouseleave代替over和out即可;

放大镜组件如下:

<html>
	<head>
	<script src="jquery.js"></script>
	<style>
		body{
			height:2000px;
		}
		#box{
			margin:50px;
			border:2px solid skyblue;
			width:200px;
			padding:5px;
			position:relative;
		}
		
		.tab-img-box{
			list-style:none;
			margin:0;
			padding:0;
			height:51px;
		}
		
		.tab-img-box li{
			float:left;
			margin:3px;
		}
		
		.tab-img-box li .tab-img{
			width:31px;
			height:48px;
			border:1px solid #ccc;
		}
		
		.tab-img-box .active .tab-img{
			border:2px solid skyblue;
		}
		
		.show-box{
			display:none;
			
		}
		
		.show-box.active{
			display:block;
		}
		
		.show-box .big{
			
			position:absolute;
			width:300px;
			height:450px;
			border:2px solid skyblue;
			left:240px;
			top:-3px;
			overflow:hidden;
			display:none;
		}
		
		.show-box .big img{
			position:absolute;
			left:0;
			top:0;
		}
		
		.show-box .small{
			position:relative;
			width:200px;
			height:300px;
			
		}
		
		.show-box .small img{
			width:200px;
			height:300px;
		}
		
		.show-box .small .glass{
			width:50px;
			height:50px;
			background:yellow;
			opacity:0.5;
			filter:alpha(opacity:50);
			position:absolute;
			left:0;
			top:0;
			display:none;
		}
		
	</style>
	<script>
		var x=0;
		var y=0;
		var osmall=null;
		var atab=null;
		
		$(function(){
			asmall=$(".small");
			atab=$(".tab-img-box").find("li");
			
			var tab1=new Tab()
			tab1.init(atab,$(".show-box"));
			
			var glass1=new Glass();
			glass1.init(asmall,".big");
		});
		
		//选项卡组件
		function Tab(){
			this.atab = null;
			this.abox = null;
		}
		
		Tab.prototype.init=function(atab,abox){
			this.atab=atab;
			this.abox=abox;
			
			var _this=this;
			this.atab.click(function(){
				_this.change($(this));
			});
		}
		
		Tab.prototype.change=function(tab){
			this.atab.removeClass("active");
			tab.addClass("active");
			this.abox.hide();
			this.abox.eq(tab.index()).show();
		}
		
		//放大镜组件
		function Glass(){
			this.asmall=null;
			this.big_name=null;
			this.x=0;
			this.y=0;
		}
		
		Glass.prototype.init=function(asmall,big_name){
			this.asmall=asmall;
			this.big_name=big_name;
			
			var _this=this;
			asmall.mouseenter(function(){
				_this.menter($(this));
				
			}).mouseleave(function(){
				_this.mleave($(this));
			}).mousemove(function(ev){
				var e = ev || event;
				_this.mmove(e,$(this));
			});
		}
		
		Glass.prototype.menter=function(osmall){
			osmall.find(".glass").show();
			osmall.parent().find(this.big_name).show();
		}
		
		Glass.prototype.mleave=function(osmall){
			osmall.find(".glass").hide();
			osmall.parent().find(this.big_name).hide();
		}
		
		Glass.prototype.mmove=function(e,osmall){
			var glass = osmall.find(".glass");
			var big = osmall.parent().find(this.big_name);
			var big_img = big.find("img");
			
			this.x = e.clientX-osmall.offset().left-glass.width()/2+$(document).scrollLeft();
			this.y = e.clientY-osmall.offset().top-glass.height()/2+$(document).scrollTop();
			
			if(this.x<0){
				this.x=0;
			}
			if(this.x>osmall.width()-glass.width()){
				this.x=osmall.width()-glass.width();
			}
			if(this.y<0){
				this.y=0;
			}
			if(this.y>osmall.height()-glass.height()){
				this.y=osmall.height()-glass.height();
			}
			
			var scale_x = this.x/(osmall.width()-glass.width());
			var scale_y = this.y/(osmall.height()-glass.height());
			
			var big_x = (big_img.width()-big.width())*scale_x;
			var big_y = (big_img.height()-big.height())*scale_y;
			
			glass.css({"left":this.x + "px","top":this.y + "px"});
			big_img.css({"left":-big_x + "px","top":-big_y + "px"});
		}
	</script>
	</head>
	<body>
		<div id="container">
			<div id="box">
				<div class="show-box active">
					<div class="small">
						<img src="img/1.jpg">
						<div class="glass"></div>
					</div>
					<div class="big">
						<img src="img/1.jpg">
					</div>
				</div>
				<div class="show-box">
					<div class="small">
						<img src="img/2.jpg">
						<div class="glass"></div>
					</div>
					<div class="big">
						<img src="img/2.jpg">
					</div>
				</div>
				<div class="show-box">
					<div class="small">
						<img src="img/3.jpg">
						<div class="glass"></div>
					</div>
					<div class="big">
						<img src="img/3.jpg">
					</div>
				</div>
				<div class="show-box">
					<div class="small">
						<img src="img/4.jpg">
						<div class="glass"></div>
					</div>
					<div class="big">
						<img src="img/4.jpg">
					</div>
				</div>
				<div class="show-box">
					<div class="small">
						<img src="img/5.jpg">
						<div class="glass"></div>
					</div>
					<div class="big">
						<img src="img/5.jpg">
					</div>
				</div>
				<ul class="tab-img-box">
					<li class="active"><img src="img/1.jpg" class="tab-img">  </li>
					<li><img src="img/2.jpg" class="tab-img">  </li>
					<li><img src="img/3.jpg" class="tab-img">  </li>
					<li><img src="img/4.jpg" class="tab-img">  </li>
					<li><img src="img/5.jpg" class="tab-img">  </li>
				</ul>
			</div>
		</div>
		
	</body>
</html>

 


3.照片墙
这个例子涉及很多小知识点:
a.布局转换,将float转为position:absolute
b.碰撞检测
c.获取数组最小值的位置
d.数组随机打乱


<html>
	<head>
	<meta charset="utf-8">
	<script src="jquery.js"></script>
	<style>
		#box,#img-ul{
			height:390px;
			width:570px;
			margin:auto;
			border:1px solid skyblue;
		}
		
		#img-ul{
			padding:0;
			margin:0;
			list-style:none;
			
		}
		
		#img-ul li img{
			width:180px;
			height:120px;
			
		}
		
		#img-ul li{
			float:left;
			margin:5px;
			position:relative;
		}
		
		#img-ul li div{
			width:180px;
			height:120px;
			position:absolute;
			left:0;
			top:0;
		}
		
		
	</style>
	<script>
		var posArr=[];
		$(function(){
			var disX=0;
			var disY=0;
			
			var aLi=$("#img-ul li");
			var zIndex=2;
			
			//布局转换
			aLi.each(function(){
				posArr.push([$(this).offset().left,$(this).offset().top]);
			});
			aLi.each(function(i,v){
				$(this).css({position:"absolute",left:posArr[i][0],top:posArr[i][1],margin:0});
				$(this).attr("i",i);   //做标记,相当于js中的oDiv.index=i一样
				
			});
			
			$("#b1").click(function(){
				var arr=[0,1,2,3,4,5,6,7,8];
				arr.sort(function(){ return 0.5 - Math.random() });
				
				for(var i in arr){
					aLi.eq(i).animate({"left":posArr[arr[i]][0],"top":posArr[arr[i]][1]});
					aLi.eq(i).attr("i",arr[i]);
				}
			});
			
			aLi.mousedown(function(ev){
				var e=ev || event;
				var nLi=null;
				disX=e.pageX-$(this).offset().left;
				disY=e.pageY-$(this).offset().top;
				$(this).css({"z-index":zIndex++});
				
				var _this = $(this);
				
				$(document).mousemove(function(ev){
					var e = ev || event;
					var x = e.pageX-disX;
					var y = e.pageY-disY;
					
					_this.css({left:x+"px",top:y+"px"});
					
					nLi=nl(aLi,_this);
					aLi.css({border:""});
					if(nLi){
						nLi.css({border:"1px solid red"});
					}
					
				});
				
				$(document).mouseup(function(){
					$(document).unbind("mousemove");
					$(document).unbind("mouseup");
					
					//切换图片位置
					if(nLi){
						tran(_this,nLi);
						nLi.css({border:"","z-index":zIndex++});
						_this.css({"z-index":zIndex++});
					}else{
						_this.animate({left:posArr[_this.attr("i")][0],top:posArr[_this.attr("i")][1]});
					}
					
				});
			});
		});
		
		//碰撞检测,检测两个元素是否碰撞
		function pz(obj1,obj2){
			var l1=obj1.offset().left;
			var t1=obj1.offset().top;
			var r1=obj1.offset().left+obj1.width();
			var b1=obj1.offset().top+obj1.height();
			
			var l2=obj2.offset().left;
			var t2=obj2.offset().top;
			var r2=obj2.offset().left+obj2.width();
			var b2=obj2.offset().top +obj2.height();
			
			if(l2>r1 || l1>r2 || t1>b2 || t2>b1){
				//先分析碰不到的情况,碰不到的情况好分析
				return false;
			}else{
				return true;
			}
		}
		
		//计算两个色块左上定点之间的距离
		function jl(obj1,obj2){
			var a=obj1.offset().left-obj2.offset().left;
			var b=obj1.offset().top-obj2.offset().top;
			
			
			return Math.sqrt(a*a+b*b);
		}
		
		//获取离鼠标所拖动色块最近的色块
		function nl(elements,obj){
			var value=9999;
			var index=-1;
			elements.each(function(i,v){
				if(obj.index() != $(this).index() && pz(obj,$(this))){
					//现在能进到这个代码块的都是鼠标所移动的色块能碰到的色块
					//我要获取能碰到的色块中,离鼠标移动色块最近的一个让他变红边框
					var ijl=jl(obj,$(this));
					if(value > ijl){
						value = ijl;
						index = i;
					}
					
				}
			});
			
			if(index == -1){
				return false;
			}
			
			return elements.eq(index);
			
		}
		
		//切换图片位置 
		function tran(obj1,obj2){
			
			obj1.animate({left:posArr[obj2.attr("i")][0],top:posArr[obj2.attr("i")][1]});
			obj2.animate({left:posArr[obj1.attr("i")][0],top:posArr[obj1.attr("i")][1]});
			//alert(obj1);
			var tmp=obj1.attr("i");
			obj1.attr("i",obj2.attr("i"));
			obj2.attr("i",tmp);
		}
	</script>
	</head>
	<body>
		<div id="container">
			<button id="b1">随机切换</button>
			<div id="box">
				<ul id="img-ul">
					<li class="img-li"><img src="img/img-1.jpg"><div></div></li>
					<li class="img-li"><img src="img/img-2.jpg"><div></div></li>
					<li class="img-li"><img src="img/img-3.jpg"><div></div></li>
					<li class="img-li"><img src="img/img-4.jpg"><div></div></li>
					<li class="img-li"><img src="img/img-5.jpg"><div></div></li>
					<li class="img-li"><img src="img/img-6.jpg"><div></div></li>
					<li class="img-li"><img src="img/img-7.jpg"><div></div></li>
					<li class="img-li"><img src="img/img-8.jpg"><div></div></li>
					<li class="img-li"><img src="img/img-9.jpg"><div></div></li>
				</ul>
			</div>
		</div>
		
	</body>
</html>

 

 

如果您需要转载,可以点击下方按钮可以进行复制粘贴;本站博客文章为原创,请转载时注明以下信息

张柏沛IT技术博客 > JS面向对象之编写组件小实例——实现选项卡,放大镜和照片墙

热门推荐
推荐新闻