自从用firefox浏览器以来,就几乎养成了一个习惯,就想用webdeveloper把一些漂亮网站的js包括css给down下来分析一下,用来学习。
百度空间的弹出窗口和拖拽效果,看起来挺不错的。现在很多知名网站都是用的这样的技术。下面把我down的js代码发出来,我分析了一部分,但是还有很多东西不明白怎么回事,没有写注释的部分,还请高手能帮我解释一下。本人属于初学,有不对的地方还请多多指教。
在声明一条吧,此代码仅做学习用,技术版权属于百度。
主要是一个叫做:popup.js的文件,如下:
/**//*********************************************** popup.js**************************************************/
//为数组array添加一个push方法
//为数组的末尾加入一个对象
if(!array.prototype.push)
{
array.prototype.push=function ()
{
var startlength=this.length;
for(var i=0;i<arguments.length;i++)
{
this[startlength+i]=arguments[i];
}
return this.length;
}
};
//对g函数的参数进行处理
function g()
{
//定义一个数组用来保存参数
var elements=new array();
//循环分析g中参数的内容
for(var i=0;i<arguments.length;i++)
{
var element=arguments[i];
//如果参数的类型为string,则获得以这个参数为id的对象
if(typeof element=='string')
{
element=document.getelementbyid(element);
}
//如果参数的长度为1
if(arguments.length==1)
{
return element;
}
//将对象加入到数组的末尾
elements.push(element);
};
return elements;
};
function.prototype.bind=function (object)
{
var __method=this;
return function ()
{
__method.apply(object,arguments);
};
};
//绑定事件
function.prototype.bindaseventlistener=function (object)
{
var __method=this;
return function (event){__method.call(object,event||window.event);};
};
object.extend=function (destination,source)
{
for(property in source)
{
destination[property]=source[property];
};
return destination;
};
if(!window.event)
{
var event=new object();
};
object.extend(
event,
{
observers:false,
element:function (event)
{
return event.target||event.srcelement;
},
isleftclick:function (event)
{
return (((event.which)&&(event.which==1))||((event.button)&&(event.button==1)));
},
pointerx:function (event)
{
return event.pagex||(event.clientx+(document.documentelement.scrollleft||document.body.scrollleft));
},
pointery:function (event)
{
return event.pagey||(event.clienty+(document.documentelement.scrolltop||document.body.scrolltop));
},
stop:function (event)
{
if(event.preventdefault)
{
event.preventdefault();
event.stoppropagation();
}
else
{
event.returnvalue=false;
event.cancelbubble=true;
};
},
findelement:function (event,tagname)
{
var element=event.element(event);
while(element.parentnode&&(!element.tagname||(element.tagname.touppercase()!=tagname.touppercase())))
element=element.parentnode;
return element;
},
_observeandcache:function (element,name,observer,usecapture)
{
if(!this.observers)
this.observers=[];
if(element.addeventlistener)
{
this.observers.push([element,name,observer,usecapture]);
element.addeventlistener(name,observer,usecapture);
}
else if(element.attachevent)
{
this.observers.push([element,name,observer,usecapture]);
element.attachevent('on'+name,observer);
};
},
unloadcache:function ()
{
if(!event.observers)
return;
for(var i=0;i<event.observers.length;i++)
{
event.stopobserving.apply(this,event.observers[i]);
event.observers[i][0]=null;
};
event.observers=false;
},
observe:function (element,name,observer,usecapture)
{
var element=g(element);
usecapture=usecapture||false;
if(name=='keypress'&&(navigator.appversion.match(/konqueror|safari|khtml/)||element.attachevent))
name='keydown';
this._observeandcache(element,name,observer,usecapture);
},
stopobserving:function (element,name,observer,usecapture)
{
var element=g(element);
usecapture=usecapture||false;
if(name=='keypress'&&(navigator.appversion.match(/konqueror|safari|khtml/)||element.detachevent))
name='keydown';
if(element.removeeventlistener)
{
element.removeeventlistener(name,observer,usecapture);
}
else if(element.detachevent)
{
element.detachevent('on'+name,observer);
};
}
}
);
event.observe(window,'unload',event.unloadcache,false);
var class=function ()
{
var _class=function ()
{
this.initialize.apply(this,arguments);
};
for(i=0;i<arguments.length;i++)
{
superclass=arguments[i];
for(member in superclass.prototype)
{
_class.prototype[member]=superclass.prototype[member];
};
};
_class.child=function ()
{
return new class(this);
};
_class.extend=function (f)
{
for(property in f)
{
_class.prototype[property]=f[property];
};
};
return _class;
};
//改变百度空间的最顶端和最低端的p的id值
//如果flag为begin,则为弹出状态的id值
//如果flag为end,则为非弹出状态的id值,即原本的id值
function space(flag)
{
if(flag=="begin")
{
var ele=document.getelementbyid("ft");
if(typeof(ele)!="#ff0000"&&ele!=null)
ele.id="ft_popup";
ele=document.getelementbyid("usrbar");
if(typeof(ele)!="undefined"&&ele!=null)
ele.id="usrbar_popup";
}
else if(flag=="end")
{
var ele=document.getelementbyid("ft_popup");
if(typeof(ele)!="undefined"&&ele!=null)
ele.id="ft";
ele=document.getelementbyid("usrbar_popup");
if(typeof(ele)!="undefined"&&ele!=null)
ele.id="usrbar";
};
};
//**************************************************popup类弹出窗口***************************************************************
var popup=new class();
popup.prototype={
//弹出窗口中框架的name名称
iframeidname:'ifr_popup',
initialize:function (config)
{
//---------------弹出对话框的配置信息------------------
//contenttype:设置内容区域为什么类型:1为另外一个html文件 | 2为自定义html字符串 | 3为confirm对话框 | 4为alert警告对话框
//ishavetitle:是否显示标题栏
//scrolltype:设置或获取对话框中的框架是否可被滚动
//isbackgroundcanclick:弹出对话框后,是否允许蒙布后的所有元素被点击。也就是如果为false的话,就会有全屏蒙布,如果为true的话,就会去掉全屏蒙布
//issupportdraging:是否支持拖拽
//isshowshadow:是否现实阴影
//isreloadonclose:是否刷新页面,并关闭对话框
//width:宽度
//height:高度
this.config=object.extend({contenttype:1,ishavetitle:true,scrolltype:'yes',isbackgroundcanclick:false,issupportdraging:true,isshowshadow:true,isreloadonclose:true,width:400,height:300},config||{});
//----------------对话框的参数值信息------------------------
//shadowwidth :阴影的宽度
//contenturl :html链接页面
//contenthtml :html内容
//callback :回调的函数名
//parameter :回调的函数名中传的参数
//confirmcon :对话框内容
//alertcon :警告框内容
//somehiddentag:页面中需要隐藏的元素列表,以逗号分割
//somehiddenele:需要隐藏的元素的id列表(和sometohidden的区别是:somehiddenele是通过getelementbyid,而sometohidden是通过getelementbytagname,里面放的是对象)
//overlay :
//coveropacity :蒙布的透明值
this.info={shadowwidth:4,title:"",contenturl:"",contenthtml:"",callback:null,parameter:null,confirmcon:"",alertcon:"",somehiddentag:"select,object,embed",somehiddenele:"",overlay:0,coveropacity:40};
//设置颜色ccolor:蒙布的背景, bcolor:内容区域的背景, tcolor:标题栏和边框的颜色,wcolor:字体的背景色
this.color={ccolor:"#eeeeee",bcolor:"#ffffff",tcolor:"#709cd2",wcolor:"#ffffff"};
this.dropclass=null;
//用来放置隐藏了的对象列表,在hiddentag方法中第一次调用
this.sometohidden=[];
//如果没有标题栏则不支持拖拽
if(!this.config.ishavetitle)
{
this.config.issupportdraging=false;
}
//初始化
this.inibuild();
},
//设置配置信息和参数内容
setcontent:function (arrt,val)
{
if(val!='')
{
switch(arrt)
{
case 'width':this.config.width=val;
break;
case 'height':this.config.height=val;
break;
case 'title':this.info.title=val;
break;
case 'contenturl':this.info.contenturl=val;
break;
case 'contenthtml':this.info.contenthtml=val;
break;
case 'callback':this.info.callback=val;
break;
case 'parameter':this.info.parameter=val;
break;
case 'confirmcon':this.info.confirmcon=val;
break;
case 'alertcon':this.info.alertcon=val;
break;
case 'somehiddentag':this.info.somehiddentag=val;
break;
case 'somehiddenele':this.info.somehiddenele=val;
break;
case 'overlay':this.info.overlay=val;
};
};
},
inibuild:function ()
{
g('dialogcase')?g('dialogcase').parentnode.removechild(g('dialogcase')):function (){};
var op=document.createelement('span');
op.id='dialogcase';
document.body.appendchild(op);
},
build:function ()
{
//设置全屏蒙布的z-index
var basezindex=10001+this.info.overlay*10;
//设置蒙布上的弹出窗口的z-index(比蒙布的z-index高2个值)
var showzindex=basezindex+2;
//定义框架名称
this.iframeidname='ifr_popup'+this.info.overlay;
//设置图片的主路径
var path="http://img.baidu.com/hi/img/";
//关闭按钮
var close='<input type="image" id="dialogboxclose" src="'+path+'dialogclose.gif" border="0" width="16" height="16" align="absmiddle" title="关闭"/>';
//使用滤镜设置对象的透明度
var cb='filter: alpha(opacity='+this.info.coveropacity+');opacity:'+this.info.coveropacity/100+';';
//设置全屏的蒙布
var cover='<p id="dialogboxbg" style="position:absolute;top:0px;left:0px;width:100%;height:100%;z-index:'+basezindex+';'+cb+'background-color:'+this.color.ccolor+';display:none;"></p>';
//设置弹出的主窗口设置
var mainbox='<p id="dialogbox" style="border:1px solid '+this.color.tcolor+';display:none;z-index:'+showzindex+';position:relative;width:'+this.config.width+'px;"><table width="100%" border="0" cellpadding="0" cellspacing="0" bgcolor="'+this.color.bcolor+'">';
//设置窗口标题栏
if(this.config.ishavetitle)
{
mainbox+='<tr height="24" bgcolor="'+this.color.tcolor+'"><td><table style="-moz-user-select:none;height:24px;" width="100%" border="0" cellpadding="0" cellspacing="0" ><tr>'+'<td width="6" height="24"></td><td id="dialogboxtitle" style="color:'+this.color.wcolor+';font-size:14px;font-weight:bold;">'+this.info.title+' </td>'+'<td id="dialogclose" width="20" align="right" valign="middle">'+close+'</td><td width="6"></td></tr></table></td></tr>';
}
else
{
mainbox+='<tr height="10"><td align="right">'+close+'</td></tr>';
};
//设置窗口主内容区域
mainbox+='<tr style="height:'+this.config.height+'px" valign="top"><td id="dialogbody" style="position:relative;"></td></tr></table></p>'+'<p id="dialogboxshadow" style="display:none;z-index:'+basezindex+';"></p>';
//如果有蒙布
if(!this.config.isbackgroundcanclick)
{
g('dialogcase').innerhtml=cover+mainbox;
g('dialogboxbg').style.height=document.body.scrollheight;
}
else
{
g('dialogcase').innerhtml=mainbox;
}
event.observe(g('dialogboxclose'),click,this.reset.bindaseventlistener(this),false);
//如果支持拖动,则设置拖动处理
if(this.config.issupportdraging)
{
dropclass=new dragdrop(this.config.width,this.config.height,this.info.shadowwidth,this.config.issupportdraging,this.config.contenttype);
g(dialogboxtitle).style.cursor=move;
};
this.lastbuild();
},
lastbuild:function ()
{
//设置confim对话框的具体内容
var confirm='<p style="width:100%;height:100%;text-align:center;"><p style="margin:20px 20px 0 20px;font-size:14px;line-height:16px;color:#000000;">'+this.info.confirmcon+'</p><p style="margin:20px;"><input id="dialogok" type="button" value=" 确定 "/> <input id="dialogcancel" type="button" value=" 取消 "/></p></p>';
//设置alert对话框的具体内容
var alert='<p style="width:100%;height:100%;text-align:center;"><p style="margin:20px 20px 0 20px;font-size:14px;line-height:16px;color:#000000;">'+this.info.alertcon+'</p><p style="margin:20px;"><input id="dialogyes" type="button" value=" 确定 "/></p></p>';
var basezindex=10001+this.info.overlay*10;
var coverifzindex=basezindex+4;
//判断内容类型决定窗口的主内容区域应该显示什么
if(this.config.contenttype==1)
{
var openiframe=<iframe width='100%' style='height:"+this.config.height+"px' name='"+this.iframeidname+"' id='"+this.iframeidname+"' src='"+this.info.contenturl+"' frameborder='0' scrolling='"+this.config.scrolltype+"'></iframe>;
var coveriframe=<p id='iframebg' style='position:absolute;top:0px;left:0px;width:1px;height:1px;z-index:"+coverifzindex+";filter: alpha(opacity=00);opacity:0.00;background-color:#ffffff;'><p>;
g(dialogbody).innerhtml=openiframe+coveriframe;
}
else if(this.config.contenttype==2)
{
g(dialogbody).innerhtml=this.info.contenthtml;
}
else if(this.config.contenttype==3)
{
g(dialogbody).innerhtml=confirm;event.observe(g('dialogok'),click,this.forcallback.bindaseventlistener(this),false);
event.observe(g('dialogcancel'),click,this.close.bindaseventlistener(this),false);
}
else if(this.config.contenttype==4)
{
g(dialogbody).innerhtml=alert;
event.observe(g('dialogyes'),click,this.close.bindaseventlistener(this),false);
};
},
//重新加载弹出窗口的高度和内容
rebuild:function ()
{
g('dialogbody').height=g('dialogbody').clientheight;
this.lastbuild();
},
show:function ()
{
//隐藏一些在info中制定的元素
this.hiddensome();
//弹出窗口居中
this.middle();
//设置阴影
if(this.config.isshowshadow)
this.shadow();
},
//设置回调函数
forcallback:function ()
{
return this.info.callback(this.info.parameter);
},
//为弹出窗口设置阴影
shadow:function ()
{
var oshadow=g('dialogboxshadow');
var odialog=g('dialogbox');oshadow['style']['position']=absolute;
oshadow['style']['background']=#000;
oshadow['style']['display']=;
oshadow['style']['opacity']=0.2;
oshadow['style']['filter']=alpha(opacity=20);
oshadow['style']['top']=odialog.offsettop+this.info.shadowwidth;
oshadow['style']['left']=odialog.offsetleft+this.info.shadowwidth;
oshadow['style']['width']=odialog.offsetwidth;oshadow['style']['height']=odialog.offsetheight;
},
//让弹出窗口居中显示
middle:function ()
{
if(!this.config.isbackgroundcanclick)
g('dialogboxbg').style.display='';
var odialog=g('dialogbox');
odialog['style']['position']=absolute;
odialog['style']['display']='';
var sclientwidth=document.body.clientwidth;
var sclientheight=document.body.clientheight;
var sscrolltop=document.body.scrolltop;
//alert(document.body.clientwidth = + sclientwidth + \ndocument.body.clientheight +sclientheight);
var sleft=(document.body.clientwidth/2)-(odialog.offsetwidth/2);
var itop=-80+(sclientheight/2+sscrolltop)-(odialog.offsetheight/2);
var stop=itop>0?itop:(sclientheight/2+sscrolltop)-(odialog.offsetheight/2);
//alert(var itop=-80+(sclientheight/2+sscrolltop)-(odialog.offsetheight/2);\n + sclientheight is + sclientheight + \nsscrolltop is + sscrolltop);
//alert(itop is + itop);
if(stop<1)
stop="20";
if(sleft<1)
sleft="20";
odialog['style']['left']=sleft;
odialog['style']['top']=stop;
//alert("sleft is " + sleft);
//alert("stop is " + stop);
},
//刷新页面,并关闭当前弹出窗口
reset:function ()
{
if(this.config.isreloadonclose)
{
top.location.reload();
};
this.close();
},
//关闭当前弹出窗口
close:function ()
{
g('dialogbox').style.display='none';
if(!this.config.isbackgroundcanclick)
g('dialogboxbg').style.display='none';
if(this.config.isshowshadow)
g('dialogboxshadow').style.display='none';
g('dialogbody').innerhtml='';
this.showsome();
},
//隐藏somehiddentag和somehiddenele中的所有元素
hiddensome:function ()
{
//隐藏somehiddentag中的所有元素
var tag=this.info.somehiddentag.split(",");
if(tag.length==1&&tag[0]=="")
{
tag.length=0;
}
for(var i=0;i<tag.length;i++)
{
this.hiddentag(tag[i]);
};
//隐藏somehiddenele中的所有逗号分割的id的元素
var ids=this.info.somehiddenele.split(",");
if(ids.length==1&&ids[0]=="")
ids.length=0;
for(var i=0;i<ids.length;i++)
{
this.hiddenele(ids[i]);
};
//改变顶部和底部的p的id值为弹出状态的id值,祥见space的实现
space("begin");
},
//隐藏一组元素
hiddentag:function (tagname)
{
var ele=document.getelementsbytagname(tagname);
if(ele!=null)
{
for(var i=0;i<ele.length;i++)
{
if(ele[i].style.display!="none"&&ele[i].style.visibility!='hidden')
{
ele[i].style.visibility='hidden';
this.sometohidden.push(ele[i]);
};
};
};
},
//隐藏单个元素
hiddenele:function (id)
{
var ele=document.getelementbyid(id);
if(typeof(ele)!="undefined"&&ele!=null)
{
ele.style.visibility='hidden';
this.sometohidden.push(ele);
}
},
//将sometohidden中保存的隐藏元素全部显示
//并恢复顶部和底部的p为原来的id值
showsome:function ()
{
for(var i=0;i<this.sometohidden.length;i++)
{
this.sometohidden[i].style.visibility='visible';
};
space("end");
}
};
//********************************************************dragdrop类(拖拽动作)************************************************************
var dragdrop=new class();
dragdrop.prototype={
initialize:function (width,height,shadowwidth,showshadow,contenttype)
{
this.dragdata=null;
this.dragdatain=null;
this.backdata=null;
this.width=width;
this.height=height;
this.shadowwidth=shadowwidth;
this.showshadow=showshadow;
this.contenttype=contenttype;
this.isdraging=false;
this.oobj=g('dialogbox');
event.observe(g('dialogboxtitle'),"mousedown",this.movestart.bindaseventlistener(this),false);
},
movestart:function (event)
{
this.isdraging=true;
if(this.contenttype==1)
{
g("iframebg").style.display="";
g("iframebg").style.width=this.width;
g("iframebg").style.height=this.height;
};
event.observe(document,"mousemove",this.mousemove.bindaseventlistener(this),false);
event.observe(document,"mouseup",this.mouseup.bindaseventlistener(this),false);
event.observe(document,"selectstart",this.returnfalse,false);
this.dragdata={x:event.pointerx(event),y:event.pointery(event)};
this.backdata={x:parseint(this.oobj.style.left),y:parseint(this.oobj.style.top)};
},
mousemove:function (event)
{
if(!this.isdraging)
return ;
var ileft=event.pointerx(event)-this.dragdata["x"]+parseint(this.oobj.style.left);
var itop=event.pointery(event)-this.dragdata["y"]+parseint(this.oobj.style.top);
if(this.dragdata["y"]<parseint(this.oobj.style.top))
itop=itop-12;
else if(this.dragdata["y"]>parseint(this.oobj.style.top)+25)
itop=itop+12;
this.oobj.style.left=ileft;
this.oobj.style.top=itop;
if(this.showshadow)
{
g('dialogboxshadow').style.left=ileft+this.shadowwidth;
g('dialogboxshadow').style.top=itop+this.shadowwidth;
};
this.dragdata={x:event.pointerx(event),y:event.pointery(event)};
document.body.style.cursor=move;
},
mouseup:function (event)
{
if(!this.isdraging)
return ;
if(this.contenttype==1)
g(iframebg).style.display=none;
document.onmousemove=null;
document.onmouseup=null;
var mousx=event.pointerx(event)-(document.documentelement.scrollleft||document.body.scrollleft);
var mousy=event.pointery(event)-(document.documentelement.scrolltop||document.body.scrolltop);
if(mousx<1||mousy<1||mousx>document.body.clientwidth||mousy>document.body.clientheight)
{
this.oobj.style.left=this.backdata[x];
this.oobj.style.top=this.backdata[y];
if(this.showshadow)
{
g('dialogboxshadow').style.left=this.backdata.x+this.shadowwidth;
g('dialogboxshadow').style.top=this.backdata.y+this.shadowwidth;
};
};
this.isdraging=false;
document.body.style.cursor=;
event.stopobserving(document,selectstart,this.returnfalse,false);
},
returnfalse:function ()
{
return false;
}
};
将上面对popup.js文件做个引用,下面是对这个js文件进行测试的html页面的代码。你可以回去很方便的测试。
<%@ page language="c#" autoeventwireup="true" codefile="popuptest.aspx.cs" inherits="popuptest" %>
<!doctype html public "-//w3c//dtd xhtml 1.0 transitional//en" "http://www.w3.org/tr/xhtml1/dtd/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<title>无标题页</title>
<script type="text/javascript" src="scripts/popup.js"></script>
<script type="text/javascript">
function showiframe()
{
var pop=new popup({ contenttype:1,isreloadonclose:false,width:400,height:500});
pop.setcontent(contenturl,default.aspx);
pop.setcontent(title,iframe框架示例);
pop.build();
pop.show();
}
function showhtmlstring()
{
var strhtml = <table border=1 style='width:90%; text-align:center;'><tr style='height:40px'><td>ds</td><td>dads</td></tr><tr style='height:40px'><td>dadas</td><td>dasd</td></tr><tr style='height:40px'><td>dadasd</td><td>dsadads</td></tr></table>;
var pop=new popup({ contenttype:2,isreloadonclose:false,width:340,height:300});
pop.setcontent(contenthtml,strhtml);
pop.setcontent(title,html字符串示例);
pop.build();
pop.show();
}
function showconfirm()
{
var pop=new popup({ contenttype:3,isreloadonclose:false,width:340,height:80});
pop.setcontent(title,confirm对话框示例);
pop.setcontent(confirmcon,confirm对话框的内容);
pop.setcontent(callback,showcallback);
pop.setcontent(parameter,{id:pcall,str:点击确定后显示的字符串,obj:pop});
pop.build();
pop.show();
}
function showalert()
{
var pop=new popup({ contenttype:4,isreloadonclose:false,width:340,height:80});
pop.setcontent(title,alert警告框示例);
pop.setcontent(alertcon,alert对话框的内容);
pop.build();
pop.show();
}
function showcallback(para)
{
var o_pop = para[obj]
var obj = document.getelementbyid(para[id]);
o_pop.close();
obj.innertext = para[str];
}
</script>
</head>
<body style="text-align:center;">
<form id="form1" runat="server">
<p>
<a href="javascript:showiframe()">iframe框架示例</a>
<br />
<a href="javascript:showhtmlstring()">html字符串示例</a>
<br />
<a href="javascript:showconfirm()">confirm对话框示例</a>
<br />
<a href="javascript:showalert()">alert警告框示例</a>
</p>
<p id="pcall" style="width:300px; height:200px; background-color:#cccccc; color:red; float:right;">
</p>
</form>
</body>
</html>
代码一堆一堆的啊!那个拖拽的不是很清楚怎么回事?上面的那个class函数也不清楚到底是怎么弄的。凡是没有写注释的地方,基本上就不是很明白。我找时间再分析分析吧!找时间把其它的注释也给写上。如果大家明白的,还请多多指教,越详细越好。