面向对象编写照片墙组件

面向对象是一种优秀的编程思想,在JS中亦是如此,在大规模的项目中,体现的愈加突出。对于一些常用功能来说,我们完全可以将其开发成一个组件,比如JQuery中的弹窗组件等,我们可以很方便使用它们,使用时只需要按照API要求填写对应配置参数,即可迅速使用。本文给大家分享一个简单的照片墙组件。该照片墙组件完全原生JS实现,功能比较简单,但实现了一般照片墙的基本效果。我们可以通过构造函数PhotoWall()实例化一个对象,并调用init()方法进行初始化。对于布局样式要求极低,甚至完全不用设置。用户可以按照自身需求喜好随意放置照片墙的位置。预览最终效果以及下载文件,请点击这里。以下是使用该组件的具体实现方法:

首先进行一些简单的布局:




	
	动态照片墙
	
	
	


	
	
然后我们来看一下具体的JS实现代码:

/* 
 * 面向对象照片墙
 * 使用构造函数PhotoWall()来创建一个对象
 * 使用init()方法初始化
 * init()发放接收默认配置参数形式为:
 * init({
 * ulId:'xxx',必填项,需初始化的对象ul的id
 * btnId:null,选填项,随机按钮的id,多个照片墙不能绑定同一按钮
 * speed:8 选填项,图片交换速度
 * })
*/

//构造函数PhotoWall()
function PhotoWall(){
	//用以设置每张图片的zIndex
	this.izIndex=2;
	//用以存放每张图片的初始位置
	this.arr=[];
	//用以保存鼠标在图片上的位置
	this.disX=null;
	this.disY=null;
	//默认参数
	this.settings={
		ulId:'photoList',
		btnId:null,
		speed:8
	};
}
/*
 * init()初始化方法:
 * 由于存在点击事件,所以使用This提前保存对象,用以修正this指向
 * 调用exchange()方法用配置参数项修改默认参数
 * 使用修改后的参数获取页面布局元素(ul、li)
 * 如果随机按钮存在,则为随机按钮添加点击事件
 * 为每一个li循环添加拖拽事件
 */

PhotoWall.prototype.init=function(opt){
	var This=this;
	
	this.exchange(this.settings,opt);
	
	this.oUl=document.getElementById(this.settings.ulId);
	this.aLi=this.oUl.getElementsByTagName('li');
	

	if(this.settings.btnId){
		this.oBtn=document.getElementById(this.settings.btnId);
		this.oBtn.οnclick=function(){This.randomBtn();};
	}

	for(var i=0;i
/*
 * exchange()方法:
 * for-in循环遍历配置参数
 * 相同项将会使用配置参数进行覆盖
 * 未设置的参数选项将会保持默认参数
 */
PhotoWall.prototype.exchange=function(obj1,obj2){
	for(var attr in obj2){
		obj1[attr]=obj2[attr];
	}
}
/* 
 * setList()方法:
 * CSS中初始为浮动定位,为每一个图片确定一个初始位置
 * 第一个for循环,将每张图的初始位置以[left,top]的形式存于arr数组
 * 第二个for循环,将每张图的浮动形式的位置转化为绝对定位的位置
 * 由于转化时的值已经包含了margin值,故清除CSS的margin值
*/
PhotoWall.prototype.setList=function(){
	for(var i=0;i
/*
 * randomBtn()方法:
 * 定义数组arr2存放index索引,判断图片个数,进行push操作
 * 目的是保证最终图片依旧按索引顺序排放,即1、2、3、4、5···
 * 将数组索引随机排序,然后使用for循环按照数组顺序排序,并修正索引值
 */

PhotoWall.prototype.randomBtn=function(){
	var arrRandom=new Array();
	for(var i=0;i
/*
 * drag()、mouseDown()、docMove()、docUp()
 * 共同构成拖拽事件处理办法
 */
PhotoWall.prototype.drag=function(obj){
	//为onmousedown事件修正this指向
	var This=this;
	//为对象添加onmousedown事件
	obj.οnmοusedοwn=function(ev){
		var ev=ev||event;
		This.mouseDown(ev,obj);
		return false;
	};
}
//onmousedown处理方法
PhotoWall.prototype.mouseDown=function(ev,obj){
	//为onmousemove事件修正this指向
	var This=this;
	//保存鼠标在图片上点击的位置
	this.disX=ev.clientX-obj.offsetLeft;
	this.disY=ev.clientY-obj.offsetTop;
	
	//当前点击图片index加一,保证点击的图片处于最上层
	obj.style.zIndex=this.izIndex++;
	
	//点击对象后,为文档添加onmousemove事件
	document.οnmοusemοve=function(ev){
		var ev=ev||event;
		This.docMove(ev,obj);
	};
	//点击对象后,为文档添加onmouseup事件
	document.οnmοuseup=function(){
		This.docUp(obj);
	};
}
//onmousemove处理方法
PhotoWall.prototype.docMove=function(ev,obj){
	var ev=ev||event;
	var n1=this.nears(obj);
	//点击对象后,如果文档上发生onmousemove事件时,随之更改图片位置
	obj.style.left=ev.clientX-this.disX+'px';
	obj.style.top=ev.clientY-this.disY+'px';
	//清除所有的图片红框
	for(var i=0;i
/*
 * nears()方法:
 * 用于寻找距离最近的一个图片对象
 * 所有距离值与value比较,一直保存最小的值,保存最小值的索引值
 * 如果存在最小距离,则返回最小距离的这个图片对象
 */
PhotoWall.prototype.nears=function(obj){
	var value=99999;
	var iIndex=-1;
	for(var i=0;i
/*
 * jl()方法:
 * 勾股定理计算并返回两图片对象的中心距离
 */
PhotoWall.prototype.jl=function(obj1,obj2){
	var a=obj1.offsetLeft-obj2.offsetLeft;
	var b=obj1.offsetTop-obj2.offsetTop;
	return Math.sqrt(a*a+b*b);
}
/*
 * pz()方法
 * 用以检测两对象是否发生碰撞,若碰撞则返回true
 */
PhotoWall.prototype.pz=function(obj1,obj2){
	var t1=obj1.offsetTop;
	var b1=obj1.offsetTop+obj1.offsetHeight;
	var l1=obj1.offsetLeft;
	var r1=obj1.offsetLeft+obj1.offsetWidth;
	
	var t2=obj2.offsetTop;
	var b2=obj2.offsetTop+obj2.offsetheight;
	var l2=obj2.offsetLeft;
	var r2=obj2.offsetLeft+obj2.offsetWidth;
	
	if(r1r2||t1>b2||b1
/*
 * startMove()与getStyle()方法为运动框架
 * 接收两个个参数
 * obj:运动的对象
 * json:一个json值对,保存运动的目标点(left,top)
 */
PhotoWall.prototype.startMove=function(obj,json){
	var This=this;
	clearInterval(obj.timer);
	obj.timer = setInterval(function(){
		
		var bBtn = true;
		
		for(var attr in json){
			
			var iCur = 0;
		
			if(attr == 'opacity'){
				if(Math.round(parseFloat(This.getStyle(obj,attr))*100)==0){
				iCur = Math.round(parseFloat(This.getStyle(obj,attr))*100);
				
				}
				else{
					iCur = Math.round(parseFloat(This.getStyle(obj,attr))*100) || 100;
				}	
			}
			else{
				iCur = parseInt(This.getStyle(obj,attr)) || 0;
			}
			
			var iSpeed = (json[attr] - iCur)/This.settings.speed;
			iSpeed = iSpeed >0 ? Math.ceil(iSpeed) : Math.floor(iSpeed);
			if(iCur!=json[attr]){
				bBtn = false;
			}
			if(attr == 'opacity'){
				obj.style.filter = 'alpha(opacity=' +(iCur + iSpeed)+ ')';
				obj.style.opacity = (iCur + iSpeed)/100;
				
			}
			else{
				obj.style[attr] = iCur + iSpeed + 'px';
			}
		}
		
		if(bBtn){
			clearInterval(obj.timer);
		}
		
	},30);

}
PhotoWall.prototype.getStyle=function(obj,attr){
	if(obj.currentStyle){
		return obj.currentStyle[attr];
	}
	else{
		return getComputedStyle(obj,false)[attr];
	}
}
这样一个简化的照片墙就算完成了,可以根据自己的需要进行添加方法。如有任何疑问,欢迎提出!

你可能感兴趣的:(JavaScript)