js弹出层.doc_第1页
js弹出层.doc_第2页
js弹出层.doc_第3页
js弹出层.doc_第4页
js弹出层.doc_第5页
已阅读5页,还剩14页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

JavaScript 仿LightBox内容显示效果 相关推荐:AlertBox 弹出层(信息提示框)效果 近来要做一个LightBox的效果(也有的叫Windows关机效果),不过不用那么复杂,能显示一个内容框就行了。这个效果很久以前就做过,无非就是一个覆盖全屏的层,加一个内容显示的层。不过showbo教了我position:fixed这个新特性,决定重写一遍。先看效果:LightBox 内容显示 ps:“定位效果”的意思是屏幕滚动也能固定位置。程序说明:要实现一个简单的LightBox效果,主要有两个部分:覆盖层和高亮层。【跨浏览器的固定定位】 首先要先说说这个东西position:fixed,它的作用是跨浏览器的固定定位。摘自详解定位与定位应用:“如让一个元素可能随着网页的滚动而不断改变自己在浏览器的位置。而现在我可以通过CSS中的一个定位属性来实现这样的一个效果,这个元素属性就是曾经不被支持的position:fixed; 他的含义就是:固定定位。这个固定与绝对定位很像,唯一不同的是绝对定位是被固定在网页中的某一个位置,而固定定位则是固定在浏览器的视框位置。”程序中很多地方利用了这个css,ie7、ff都支持这个css,但ie6不支持,程序中只能是在ie6模拟这个效果。 【覆盖层】覆盖层的作用是把焦点限制在高亮层上,原理是通过一个绝对定位的层(通常使用div),设置它的宽度和高度以致能覆盖整个屏幕(包括缩放和滚动浏览器的情况下),再给它设置一个比较高的zIndex来层叠在原有内容之上(但要比高亮层小),这样用户就只能点到这个层之上的内容了。如果初始化时没有提供覆盖层对象,程序中会自动创建:this.Lay=$(this.options.Lay)|document.body.insertBefore(document.createElement(div),document.body.childNodes0);其中由于document.body.appendChild()导致IE已终止操作bug,所以用了insertBefore。【覆盖屏幕】覆盖层的关键就是如何做到覆盖整个屏幕(锁定整个页面),支持position:fixed的话很简单:with(this.Lay.style)display=none;zIndex=this.zIndex;left=top=0;position=fixed;width=height=100%;这样能把浏览器的视框覆盖了,其中使用了fixed样式,这里的意思是定位在浏览器的视框,并100%覆盖。注意不要理解错为这个层覆盖了整个页面,它只是把浏览器可视的部分覆盖了来达到效果。ie6不支持怎么办?有几个方法:1,做一个覆盖视框的层,并在onscroll时相应移动,在onresize时重新设大小;2,做一个覆盖视框的层,在样式上模拟fixed效果;3,做一个层覆盖了整个页面的层,并在onresize时重新设大小;方法1的缺点是滚动时很容易露出马脚,而且不好看;方法2的缺点是需要页面结构的改动和body样式的修改,绝对不是好的架构;而我用的是方法3,有更好的方法欢迎提出。用这个方法只要把position设为absolute,并使用一个_resize方法来设置width和height即可:Codethis.Lay.style.position=absolute;this._resize=Bind(this,function()this.Lay.style.width=Math.max(document.documentElement.scrollWidth,document.documentElement.clientWidth)+px;this.Lay.style.height=Math.max(document.documentElement.scrollHeight,document.documentElement.clientHeight)+px;);要注意的是scrollHeight和clientHeight的区别(用Height容易测试),顺带还有offsetHeight,手册上的说明:scrollHeight:Retrieves the scrolling height of the object.clientHeight:Retrieves the height of the object including padding, but not including margin, border, or scroll bar.offsetHeight:Retrieves the height of the object relative to the layout or coordinate parent, as specified by the offsetParentproperty. 我的理解是:scrollHeight是对象的内容的高度;clientHeight是对象的可视部分高度;offsetHeight是clientHeight加上border和滚动条本身高度。举个例子吧,先说说clientHeight和offsetHeight的区别(在ie7中测试):测的是外面的div,offsetHeight和clientHeight相差17(分别是83和100),这个相差的就是那个滚动条本身的高度。再看看clientHeight和scrollHeight的区别(下面是模拟在ie中的情况):可以看到clientHeight不受内容影响,都是83,即内容有没有超过对象高度都不受影响,但scrollHeight会受内容高度影响,而且从测试可以意识到:当有滚动条时,覆盖层的高度应该取scrollHeight(内容高度);当没有滚动条时,覆盖层的高度应该取clientHeight(视框高度)。而恰好两个情况都是取两者中比较大的值,所以就有了以下程序: Math.max(document.documentElement.scrollHeight,document.documentElement.clientHeight)+px;设宽度时是不包括滚动条部分的而documentElement一般也没有border,所以不需要offsetWidth。上面可以看到我用的是documentElement而不是body,手册上是这样说的:Retrieves a reference to the root node of the document.意思是整个文档的根节点,其实就是html节点(body的上一级),注意这是在XHTML的标准下。上面可以看到我们取值的对象是整个文档而不只是body,所以这里用documentElement。要注意的是在window的onresize事件中scrollWidth和clientWidth的值会产生变化,程序中在onresize中使用_resize方法重新设置宽度高度:if(isIE6)this._resize();window.attachEvent(onresize,this._resize);【覆盖select】自定义的层给select遮挡住是一个老问题了,不过可喜的是ie7和ff都已经支持select的zIndex,只要给层设定高的zIndex就能覆盖select了,可惜对于ie6这个问题还是需要解决。覆盖select据我所知有两个比较好的方法:1,显示层时,先隐藏select,关闭层时再重新显示;2,用一个iframe作为层的底,来遮住select。方法1应该都明白,方法2就是利用iframe可以覆盖select的特性,只要把一个iframe作为层的底部就可以覆盖下面的select了,程序中是这样使用的:this.Lay.innerHTML=可以看出这个透明的iframe也以同样覆盖整个页面,如果是有内容显示的页面最好设置z-index:-1;确保iframe在层的底部。个人觉得使用方法2比较好,但始终是改变了页面结构,有时会比较难控制,至于方法1就比较容易方便。【高亮层】高亮层就是用来显示内容的层,没什么看头,所以特意加了些效果在上面,吸引一下眼球。有兴趣的话可以结合拖放效果和渐变效果,做出更好的效果。【固定定位】这里“固定定位”的意思是当滚动滚动条时,高亮层依然保持在浏览器对应的位置上,把Fixed设为true就会开启这个效果。同样对于支持fixed的浏览器很简单,只要把position设为fixed就行了,这个样式本来就是这样使用的,但可怜的ie6只能模拟了。ie6模拟的原理是在onscroll事件中,不断根据滚动的距离修正top和left。首先设置position为absolute,要注意的是position要在覆盖层显示之前显示,否则计算覆盖层宽高时会计算偏差(例如把页面撑大)。再给onscroll事件添加定位函数_fixed来修正滚屏参数:this.Fixed&window.attachEvent(onscroll,this._fixed);定位函数_fixed是这样的:this._fixed=Bind(this,function()this.Center?this.SetCenter():this.SetFixed(););可以看出在_fixed中,当设置了居中显示时会执行SetCenter程序(后面会说明),否则就执行SetFixed程序。先说说SetFixed程序的原理,就是把当前scrollTop减去_top值(上一个scrollTop值)再加上当前的offsetTop,就得到要设置的top值了:Codethis.Box.style.top=document.documentElement.scrollTop-this._top+this.Box.offsetTop+px;this.Box.style.left=document.documentElement.scrollLeft-this._left+this.Box.offsetLeft+px;this._top=document.documentElement.scrollTop;this._left=document.documentElement.scrollLeft;【居中显示】“居中显示”的意思是高亮层位于视框左右上下居中的位置。实现这个有两个方法:1,视框宽度减去高亮层宽度的一半就是居中需要的left值;2,先设置left值为50%,然后marginLeft设为负的高亮层宽度的一半。方法1相对方法2需要多一个视框宽度,而且方法2在缩放浏览器时也能保持居中,明显方法2是更好,不过用margin会影响到left和top的计算,必须注意(例如SetFix修正的地方)。这里我选择了方法2,还要注意offsetWidth和offsetHeight需要在高亮层显示之后才能获取,所以定位程序需要放到高亮层显示之后:Codethis.Box.style.top=this.Box.style.left=50%;if(this.Fixed)this.Box.style.marginTop=-this.Box.offsetHeight/2+px;this.Box.style.marginLeft=-this.Box.offsetWidth/2+px;elsethis.SetCenter();其中如果不是固定定位,需要用SetCenter程序来修正滚屏参数,SetCenter程序是这样的:Codethis.Box.style.marginTop=document.documentElement.scrollTop-this.Box.offsetHeight/2+px;this.Box.style.marginLeft=document.documentElement.scrollLeft-this.Box.offsetWidth/2+px;【比较文档位置】在ie6当不显示覆盖层时需要另外隐藏select,这里使用了“覆盖select”的方法1,值得留意的是这里加了个select是否在高亮层的判断:Codethis._select.length=0;Each(document.getElementsByTagName(select),Bind(this,function(o)if(!Contains(this.Box,o)o.style.visibility=hidden;this._select.push(o);)其中Contains程序是这样的:varContains=function(a,b)returna.contains?a!=b&a.contains(b):!(pareDocumentPosition(b)&16);作用是返回a里面是否包含b,里面用到了两个函数,分别是ie的contains和ff(dom)的compareDocumentPosition。其中contains手册里是这样写的:Checks whether the given element is contained within the object. 意思是检测所给对象是否包含在指定对象里面。注意如果所给对象就是指定对象本身也会返回true,虽然这样不太合理。而ff的compareDocumentPosition功能更强大。参考Comparing Document Position看下表:从NodeA.compareDocumentPosition(NodeB)返回的结果:BitsNumberMeaning0000000Elements are identical.0000011The nodes are in different documents (or one is outside of a document).0000102Node B precedes Node A.0001004Node A precedes Node B.0010008Node B contains Node A.01000016Node A contains Node B.10000032For private use by the browser.从这里可以看出NodeA.compareDocumentPosition(NodeB) & 16的意思是当第5位数是“1”时才返回16,也就是只有NodeA包含NodeB时返回16(&是位与运算)。ps:为什么不直接pareDocumentPosition(b)=16,我也不清楚。程序代码: CodevarisIE=(document.all)?true:false;varisIE6=isIE&(/MSIE(d).0/i.exec(navigator.userAgent)01=6);var$=function(id)returnstring=typeofid?document.getElementById(id):id;varClass=create:function()returnfunction()this.initialize.apply(this,arguments);varExtend=function(destination,source)for(varpropertyinsource)destinationproperty=sourceproperty;varBind=function(object,fun)returnfunction()returnfun.apply(object,arguments);varEach=function(list,fun)for(vari=0,len=list.length;ilen;i+)fun(listi,i);varContains=function(a,b)returna.contains?a!=b&a.contains(b):!(pareDocumentPosition(b)&16);varOverLay=Class.create();OverLtotype=initialize:function(options)this.SetOptions(options);this.Lay=$(this.options.Lay)|document.body.insertBefore(document.createElement(div),document.body.childNodes0);this.Color=this.options.Color;this.Opacity=parseInt(this.options.Opacity);this.zIndex=parseInt(this.options.zIndex);with(this.Lay.style)display=none;zIndex=this.zIndex;left=top=0;position=fixed;width=height=100%;if(isIE6)this.Lay.style.position=absolute;/ie6设置覆盖层大小程序this._resize=Bind(this,function()this.Lay.style.width=Math.max(document.documentElement.scrollWidth,document.documentElement.clientWidth)+px;this.Lay.style.height=Math.max(document.documentElement.scrollHeight,document.documentElement.clientHeight)+px;);/遮盖selectthis.Lay.innerHTML=,/设置默认属性SetOptions:function(options)this.options=/默认值Lay:null,/覆盖层对象Color:#fff,/背景色Opacity:50,/透明度(0-100)zIndex:1000/层叠顺序;Extend(this.options,options|);,/显示Show:function()/兼容ie6if(isIE6)this._resize();window.attachEvent(onresize,this._resize);/设置样式with(this.Lay.style)/设置透明度isIE?filter=alpha(opacity:+this.Opacity+):opacity=this.Opacity/100;backgroundColor=this.Color;display=block;,/关闭Close:function()this.Lay.style.display=none;if(isIE6)window.detachEvent(onresize,this._resize);varLightBox=Class.create();LightBtotype=initialize:function(box,options)this.Box=$(box);/显示层this.OverLay=newOverLay(options);/覆盖层this.SetOptions(options);this.Fixed=!this.options.Fixed;this.Over=!this.options.Over;this.Center=!this.options.Center;this.onShow=this.options.onShow;this.Box.style.zIndex=this.OverLay.zIndex+1;this.Box.style.display=none;/兼容ie6用的属性if(isIE6)this._top=this._left=0;this._select=;this._fixed=Bind(this,function()this.Center?this.SetCenter():this.SetFixed(););,/设置默认属性SetOptions:function(options)this.options=/默认值Over:true,/是否显示覆盖层Fixed:false,/是否固定定位Center:false,/是否居中onShow:function()/显示时执行;Extend(this.options,options|);,/兼容ie6的固定定位程序SetFixed:function()this.Box.style.top=document.documentElement.scrollTop-this._top+this.Box.offsetTop+px;this.Box.style.left=document.documentElement.scrollLeft-this._left+this.Box.offsetLeft+px;this._top=document.documentElement.scrollTop;this._left=document.documentElement.scrollLeft;,/兼容ie6的居中定位程序SetCenter:function()this.Box.style.marginTop=document.documentElement.scrollTop-this.Box.offsetHeight/2+px;this.Box.style.marginLeft=document.documentElement.scrollLeft-this.Box.offsetWidth/2+px;,/显示Show:function(options)/固定定位this.Box.style.position=this.Fixed&!isIE6?fixed:absolute;/覆盖层this.Over&this.OverLay.Show();this.Box.style.display=block;/居中if(this.Center)this.Box.style.top=this.Box.style.left=50%;/设置marginif(this.Fixed)this.Box.style.marginTop=-this.Box.offsetHeight/2+px;this.Box.style.marginLeft=-this.Box.offsetWidth/2+px;elsethis.SetCenter();/兼容ie6if(isIE6)if(!this.Over)/没有覆盖层ie6需要把不在Box上的select隐藏this._select.length=0;Each(document.getElementsByTagName(select),Bind(this,function(o)if(!Contains(this.Box,o)o.style.visibility=hidden;this._select.push(o);)/设置显示位置this.Center?this.SetCenter():this.Fixed&this.SetFixed();/设置定位this.Fixed&window.attachEvent(onscroll,this._fixed);this.onShow();,/关闭Close:function()this.Box.style.display=none;this.OverLay.Close();if(isIE6)window.detachEvent(onscroll,this._fixed);Each(this._select,function(o)o.style.visibility=visible;);使用说明: 首先要有一个高亮层:Code.lightboxwidth:300px;background:#FFFFFF;border:1pxsolid#ccc;line-height:25px;top:20%;left:20%;.lightboxdtbackground:#f4f4f4;padding:5px;LightBox内容显示至于覆盖层一般不需要另外设了,接着就可以实例化一个LightBox:varbox=newLightBox(idBox);打开和关闭LightBox分别是Show()和Close()方法,其中LightBox有下面几个属性:属性:默认值/说明Over:true,/是否显示覆盖层Fixed:false,/是否固定定位Center:false,/是否居中onShow:function()/显示时执行还有OverLay属性是覆盖层对象,它也有几个属性:属性:默认值/说明Lay:null,/覆盖层对象Color:#fff,/背景色Opacity:50,/透明度(0-100)zIndex:1000/层叠顺序完整实例下载转载请注明出处:/cloudgamer/ 如有任何建议或疑问,欢迎留言讨论。如果觉得文章不错的话,欢迎点一下右下角的推荐。程序中包含的js工具库CJL.0.1.min.js,原文在这里。分类: Javascript标签: JavaScript, fixed, 覆盖层, 高亮层, contains, LightBox, OverLay, compareDocumentPosition, 遮罩层绿色通道: 好文要顶 关注我 收藏该文与我联系 cloudgamer关注 - 5粉丝 - 933 荣誉:推荐博客+加关注 30 0 (请您对文章做出评价) 博主前一篇:JavaScript 渐变效果 博主后一篇:图片切割系统posted 2008-09-15 02:57 cloudgamer 阅读(127981) 评论(256) 编辑 收藏=0?(document.documentElement.scrollTop - this.Box.offsetHeight / 2 + px):(-this.Box.offsetTop + px);this.Box.style.marginLeft = (this.Box.offsetLeft+(document.documentElement.scrollLeft - this.Box.offsetWidth / 2)=0?(document.documentElement.scrollLeft - this.Box.offsetWidth / 2 + px):(-this.Box.offsetLeft + px);虽然不会超出窗口了,可是还是有问题。this.Box.offsetTop 的值不断变化导致窗口弹出位置变动 #210楼楼主 2010-09-26 21:57 cloudgamer steven g如果居中也超过就没办法了支持(0)反对(0) #211楼 2010-10-02 10:17 笨蛋的座右铭 无爱的新号:笨蛋的座右铭ps:为什么不直接pareDocumentPosition(b) = 16,我也不清楚。我来解释一下:000000 & 0 Elements are identical. 000001 & 1 The nodes are in different documents (.000010 & 2 Node B precedes Node A. 000100 & 4 Node A precedes Node B. 001000 & 8 Node B contains Node A. 010000 & 16 Node A contains Node B. 100000 & 32 For private use by the browser. 111111得出结论:在1,2,4,8,16,32只,16只有&16才为1,其它都为0,所以用!pareDocumentPosition(b) & 16支持(0)反对(0) #212楼楼主 2010-10-02 13:31 cloudgamer 笨蛋的座右铭010000十进制就是16支持(0)反对(0) #213楼 2010-10-02 14:24 笨蛋的座右铭 引用cloudgamer:笨蛋的座右铭010000十进制就是16给你看一段代码,你就会明白为什么不能用=16,而必须用&16了:?12345678910111213window.onload = function() var A = document.getElementById(parent), B = document.getElementById(child); alert(A.compareDocumentPosition(B);/B与A不相连,B在A的后面,B被A包含 4+16 = 20 compareDocumentPosition方法 本例子请在标准浏览器中运行。 说明一下:这是我从徒正美的blog的找到的一案例,也是一篇关于contains的。这时候=16是错误的,而&16是正确的。结论:其实上这是一种设计,一种位运算算法的典型应用,以当前compareDocumentPosition这个案例来说,他含概了从000000到111111的所有可能,唯有用&运算符,才能得出最严谨的答案支持(0)反对(0) #214楼楼主 2010-10-02 15:25 cloudgamer 笨蛋的座右铭哦谢谢支持(0)反对(0) #215楼 2010-10-09 14:41 hows 真的很厉害,我佩服博主!能逐个逐个恢复,实在少见啊,我想请教你的这段代码怎么在页面加载的时候,就打开窗口!我只要你的几个功能,都修改好了,就是不知道该怎么在 -打开窗口不知道多久才能恢复我,在线等啊!太感谢了,支持(0)反对(0) #216楼楼主 2010-10-09 14:52 cloudgamer hows在window.onload=function()xxxxx写就行了吧支持(0)反对(0) #217楼 2010-10-09 15:12 hows 仔细看了所有的评论,和博主的回复,都没有提到我上面的问题。直接用body onload=box.show();肯定是不行的;box是定义的局部变量,再直接根据层的id;(id=idBox)显示,又好像是不行的。我想做的就是在打开首页时,弹出公告层并把其他页面内容屏蔽掉,关闭后,才能操作页面。支持(0)反对(0) #218楼 2010-10-09 15:18 hows 可以了!应该可以打开多个同样的层吧,我想一条公告显示一个层,也许有很多层都需要显示!逐个关闭后,才可以操作页面!我先试一试!谢谢博主!你真帅,技术帅,心也帅!羡慕你!支持(0)反对(0) #219楼楼主 2010-10-09 15:38 cloudgamer hows可以new多几个实例就行支持(0)反对(0) #220楼 2010-10-10 15:43 newEggRock 楼主,请教个很棘手的问题,我想用一个黑色透明DIV遮住页面,再弹个DIV让用户操作,就像你例子里那种,遇到个问题就是,office web components 组件 遮不住,比如说在html里加句 页面就显示一个excel 出来 这个excel 怎么都遮不住,尝试用 iframe 能遮住,但不能让遮罩看起来透明的,直接把excel 挡住看不到了。让iframe透明 好像又遮不住。请楼主援手。谢谢支持(0)反对(0) #221楼楼主 2010-10-10 21:26 cloudgamer newEggRock程序的遮罩就是用透明的iframe的啊支持(0)反对(0) #222楼 2010-10-11 11:41 hows 请教一下,为什么直接把代码放到jsp,就没有反应啊?放到jsp运行后,就直接看到层,也没有屏蔽的功能,事件也没有反应!想了一个早上了啊!犯困了!支持(0)反对(0) #223楼楼主 2010-10-11 11:47 cloudgamer hows用调试器检查一下什么问题就行了吧支持(0)反对(0) #224楼 2010-10-11 14:07 hows 终于可以运行了,谢谢!我的技术还真烂!支持(0)反对(0) #225楼楼主 2010-10-11 14:08 cloudgamer

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论