1、JavaScript 仿 LightBox 内容显示效果 相关推荐: AlertBox 弹出层(信息提示框)效果 近来要做一个 LightBox 的效果(也有的叫 Windows 关机效果),不过不用那么复杂,能显示一个内容框就行了。这个效果很久以前就做过,无非就是一个覆盖全屏的层,加一个内容显示的层。不过 showbo教了我 position:fixed 这个新特性,决定重写一遍。先看效果:覆 盖 select测 试ps:“定位效果”的意思是屏幕滚动也能固定位置。程序说明:要实现一个简单的 LightBox 效果,主要有两个部分:覆盖层和高亮层。【跨浏览器的固定定位】 首先要先说说这个东西
2、position:fixed,它的作用是跨浏览器的固定定位。摘自详解定位与定位应用:“如让一个元素可能随着网页的滚动而不断改变自己在浏览器的位置。而现在我可以通过 CSS中的一个定位属性来实现这样的一个效果,这个元素属性就是曾经不被支持的 position:fixed; 他的含义就是:固定定位。这个固定与绝对定位很像,唯一不同的是绝对定位是被固定在网页中的某一个位置,而固定定位则是固定在浏览器的视框位置。”程序中很多地方利用了这个 css,ie7、ff 都支持这个 css,但 ie6 不支持,程序中只能是在ie6 模拟这个效果。 【覆盖层】覆盖层的作用是把焦点限制在高亮层上,原理是通过一个绝对
3、定位的层(通常使用 div),设置它的宽度和高度以致能覆盖整个屏幕(包括缩放和滚动浏览器的情况下),再给它设置一个比较高的 zIndex 来层叠在原有内容之上(但要比高亮层小),这样用户就只能点到这个层之上的内容了。如果初始化时没有提供覆盖层对象,程序中会自动创建:this.Lay = $(this.options.Lay) | document.body.insertBefore(document.createElement(“div“), document.body.childNodes0);其中由于 document.body.appendChild()导致 IE 已终止操作 bug,所
4、以用了insertBefore。【覆盖屏幕】覆盖层的关键就是如何做到覆盖整个屏幕(锁定整个页面),支持 position:fixed 的话很简单:with(this.Lay.style) display = “none“; zIndex = this.zIndex; left = top = 0; position = “fixed“; width = height = “100%“; 这样能把浏览器的视框覆盖了,其中使用了 fixed 样式,这里的意思是定位在浏览器的视框,并 100%覆盖。注意不要理解错为这个层覆盖了整个页面,它只是把浏览器可视的部分覆盖了来达到效果。ie6 不支持怎么办?
5、有几个方法:1,做一个覆盖视框的层,并在 onscroll 时相应移动,在 onresize 时重新设大小;2,做一个覆盖视框的层,在样式上模拟 fixed 效果;3,做一个层覆盖了整个页面的层,并在 onresize 时重新设大小;方法 1 的缺点是滚动时很容易露出马脚,而且不好看;方法 2 的缺点是需要页面结构的改动和body 样式的修改,绝对不是好的架构;而我用的是方法 3,有更好的方法欢迎提出。用这个方法只要把 position 设为 absolute,并使用一个_resize 方法来设置 width 和 height即可:Code要注意的是 scrollHeight 和 client
6、Height 的区别(用 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 co
7、ordinate parent, as specified by the offsetParent property. 我的理解是:scrollHeight 是对象的内容的高度;clientHeight 是对象的可视部分高度;offsetHeight 是 clientHeight 加上 border 和滚动条本身高度。举个例子吧,先说说 clientHeight 和 offsetHeight 的区别(在 ie7 中测试):测的是外面的 div,offsetHeight 和 clientHeight 相差 17(分别是 83 和 100),这个相差的就是那个滚动条本身的高度。再看看 client
8、Height 和 scrollHeight 的区别(下面是模拟在 ie 中的情况) :可以看到 clientHeight 不受内容影响,都是 83,即内容有没有超过对象高度都不受影响,但scrollHeight 会受内容高度影响,而且从测试可以意识到:当有滚动条时,覆盖层的高度应该取 scrollHeight(内容高度);当没有滚动条时,覆盖层的高度应该取 clientHeight(视框高度)。而恰好两个情况都是取两者中比较大的值,所以就有了以下程序: Math.max(document.documentElement.scrollHeight, document.documentElemen
9、t.clientHeight) + “px“;设宽度时是不包括滚动条部分的而 documentElement 一般也没有 border,所以不需要offsetWidth。上面可以看到我用的是 documentElement 而不是 body,手册上是这样说的:Retrieves a reference to the root node of the document.意思是整个文档的根节点,其实就是 html 节点(body 的上一级),注意这是在 XHTML 的标准下。上面可以看到我们取值的对象是整个文档而不只是 body,所以这里用documentElement。要注意的是在 window
10、 的 onresize 事件中 scrollWidth 和 clientWidth 的值会产生变化,程序中在 onresize 中使用_resize 方法重新设置宽度高度:if(isIE6) this._resize(); window.attachEvent(“onresize“, this._resize); 【覆盖 select】自定义的层给 select 遮挡住是一个老问题了,不过可喜的是 ie7 和 ff 都已经支持 select 的zIndex,只要给层设定高的 zIndex 就能覆盖 select 了,可惜对于 ie6 这个问题还是需要解决。覆盖 select 据我所知有两个比较
11、好的方法:1,显示层时,先隐藏 select,关闭层时再重新显示;2,用一个 iframe 作为层的底,来遮住 select。方法 1 应该都明白,方法 2 就是利用 iframe 可以覆盖 select 的特性,只要把一个 iframe 作为层的底部就可以覆盖下面的 select 了,程序中是这样使用的:this.Lay.innerHTML = 可以看出这个透明的 iframe 也以同样覆盖整个页面,如果是有内容显示的页面最好设置 z-index:-1;确保 iframe 在层的底部。个人觉得使用方法 2 比较好,但始终是改变了页面结构,有时会比较难控制,至于方法 1 就比较容易方便。【高亮
12、层】高亮层就是用来显示内容的层,没什么看头,所以特意加了些效果在上面,吸引一下眼球。有兴趣的话可以结合拖放效果和渐变效果,做出更好的效果。【固定定位】这里“固定定位”的意思是当滚动滚动条时,高亮层依然保持在浏览器对应的位置上,把 Fixed设为 true 就会开启这个效果。同样对于支持 fixed 的浏览器很简单,只要把 position 设为 fixed 就行了,这个样式本来就是这样使用的,但可怜的 ie6 只能模拟了。ie6 模拟的原理是在 onscroll 事件中,不断根据滚动的距离修正 top 和 left。首先设置 position 为 absolute,要注意的是 position
13、 要在覆盖层显示之前显示,否则计算覆盖层宽高时会计算偏差(例如把页面撑大)。再给 onscroll 事件添加定位函数_fixed 来修正滚屏参数:this.Fixed 定位函数_fixed 是这样的:this._fixed = Bind(this, function() this.Center ? this.SetCenter() : this.SetFixed(); );可以看出在_fixed 中,当设置了居中显示时会执行 SetCenter 程序(后面会说明),否则就执行 SetFixed 程序。先说说 SetFixed 程序的原理,就是把当前 scrollTop 减去_top 值(上一个
14、 scrollTop 值)再加上当前的 offsetTop,就得到要设置的 top 值了:Code【居中显示】“居中显示”的意思是高亮层位于视框左右上下居中的位置。实现这个有两个方法:1,视框宽度减去高亮层宽度的一半就是居中需要的 left 值;2,先设置 left 值为 50%,然后 marginLeft 设为负的高亮层宽度的一半。方法 1 相对方法 2 需要多一个视框宽度,而且方法 2 在缩放浏览器时也能保持居中,明显方法2 是更好,不过用 margin 会影响到 left 和 top 的计算,必须注意(例如 SetFix 修正的地方)。这里我选择了方法 2,还要注意 offsetWidt
15、h 和 offsetHeight 需要在高亮层显示之后才能获取,所以定位程序需要放到高亮层显示之后:Code其中如果不是固定定位,需要用 SetCenter 程序来修正滚屏参数,SetCenter 程序是这样的:Code【比较文档位置】在 ie6 当不显示覆盖层时需要另外隐藏 select,这里使用了“覆盖 select”的方法 1,值得留意的是这里加了个 select 是否在高亮层的判断:Code其中 Contains 程序是这样的:var Contains = function(a, b)return a.contains ? a != b 作用是返回 a 里面是否包含 b,里面用到了两个
16、函数,分别是 ie 的 contains 和 ff(dom)的compareDocumentPosition。其中 contains 手册里是这样写的:Checks whether the given element is contained within the object. 意思是检测所给对象是否包含在指定对象里面。注意如果所给对象就是指定对象本身也会返回true,虽然这样不太合理。而 ff 的 compareDocumentPosition 功能更强大。参考 Comparing Document Position 看下表:从 NodeA.compareDocumentPosition(
17、NodeB)返回的结果:Bits Number Meaning000000 0 Elements are identical.000001 1 The nodes are in different documents (or one is outside of a document).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
18、 the browser.从这里可以看出 NodeA.compareDocumentPosition(NodeB) 打开和关闭 LightBox 分别是 Show()和 Close()方法,其中 LightBox 有下面几个属性:属性:默认值/说明Over:true,/是否显示覆盖层Fixed:false,/是否固定定位Center:false,/是否居中onShow:function()/显示时执行还有 OverLay 属性是覆盖层对象,它也有几个属性:属性:默认值/说明Lay:null,/覆盖层对象Color:“#fff“,/背景色Opacity:50,/透明度(0-100)zIndex:
19、1000/层叠顺序完整实例下载转载请注明出处:http:/ 如有任何建议或疑问,欢迎留言讨论。如果觉得文章不错的话,欢迎点一下右下角的推荐。程序中包含的 js 工具库 CJL.0.1.min.js,原文在这里。分类: Javascript标签: JavaScript, fixed, 覆盖层, 高亮层, contains, LightBox, OverLay, compareDocumentPosition, 遮罩层绿色通道: 好文要顶 关注我 收藏该文与我联系 cloudgamer关注 - 5粉丝 - 933 荣誉:推荐博客+加关注 30 0 (请您对文章做出评价) 博主前一篇: JavaSc
20、ript 渐变效果 博主后一篇:图片切割系统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
21、?(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)
22、= 16,我也不清楚。我来解释一下:000000 alert(A.compareDocumentPosition(B);/B 与 A 不相连,B 在 A 的后面,B 被 A 包含 4+16 = 20 compareDocumentPosition 方法 本例子请在标准浏览器中运行。 说明一下:这是我从徒正美的 blog 的找到的一案例,也是一篇关于 contains 的。这时候=16 是错误的,而) 加上 ;wmode=“transparent“ 。其他的都没有修改,在 IE ,360,火狐,谷歌 测试了都可以。关闭覆盖层之后,可以正常操作。希望这种做法不会有错。如果有知道这方面的高手,请指点
23、一下!谢谢!支持(0)反对(0)#239 楼楼主 2010-10-13 11:14 cloudgamer hows哦我上面也已经说了设置透明支持(0)反对(0)#240 楼 2010-11-08 13:58 haonos newEggRock用 iframe 就能遮住最好是隐藏支持(0)反对(0)#241 楼 2010-12-10 15:19 路过春秋 很强悍,我彻底拜服了.支持(0)反对(0)#242 楼 2011-03-22 16:02 沙琪玛 很棒 谢谢 转载了支持(0)反对(0)#243 楼楼主 2011-03-23 11:26 cloudgamer haonos路过春秋沙琪玛谢谢支持
24、支持(0)反对(0)#244 楼 2011-03-24 10:34 gonganruyi 您好,我想问下 如果我在 iframe 里面使用当前 js 如何让他全屏弹出?支持(0)反对(0)#245 楼楼主 2011-03-24 11:19 cloudgamer gonganruyi目前没其他办法 只能在最顶层做支持(0)反对(0)#246 楼 2011-04-13 09:54 前端小子 未注册用户 楼主,你很强了,是否你写过跨 frame 的弹出,能否给点思路,或者给个 demo,不胜感激,学习中!#247 楼楼主 2011-04-14 09:58 cloudgamer 前端小子问题同上支持(
25、0)反对(0)#248 楼 2011-05-11 09:27 Doliet未注册用户 学习了#249 楼 2011-09-06 15:38 hiuiuf未注册用户 请问,如果我是想页面打开的时候判断来源,比如如果是通过百度搜索打开网站页面的,就会显示这样一个遮罩,如果是直接输入网址打开页面的,那就不显示遮罩,要怎么实现呢?#250 楼 2011-11-25 11:21 llllboy未注册用户 楼主 我在层里面加了下拉列表设置了自动回发 选择下拉列表后 页面刷新这个层就关闭了我想问 怎么才能让他不关闭呢?层的现实 能不能在页面加载的时候控制到呢?#251 楼 2011-11-28 17:19
26、llllboy未注册用户 LZ 我用了你的这个弹出框但是在 IE6 下 报 JS 错误啊说 LightBox 找不到 怎么回事啊?求助啊 !如果 LZ 看到了 就发邮件到我邮箱 我们沟通行么?#252 楼 2012-01-13 14:22 16fly未注册用户 如果能加上一个当弹出框显示就隐藏右边的滚动条就好了!我做的不兼容 IE.#253 楼 2012-02-18 19:27 ISIWA.CN未注册用户 丝袜 制服 写真 偷拍 #254 楼 2012-03-13 14:19 return O 这个实现的兼容性很好,在各种 browser 中都没有太大的偏差。我自己也写过模拟弹出框,但从来就没
27、有正常工作过。这个实现刚好可以作为参考,不过代码中借鉴了很多 JS 库的格式,作为初学者,看起来很吃力啊 看来还是要深究一下 JS 的面向对象编程.支持(0)反对(0)#255 楼 2012-03-13 14:19 return O 这个实现的兼容性很好,在各种 browser 中都没有太大的偏差。我自己也写过模拟弹出框,但从来就没有正常工作过。这个实现刚好可以作为参考,不过代码中借鉴了很多 JS 库的格式,作为初学者,看起来很吃力啊 看来还是要深究一下 JS 的面向对象编程.支持(0)反对(0)#256 楼 2012-04-27 10:32 这样人 楼主:我是一个初学者,从事 java、多米诺、移动办公 oa,但是学的越多就越不精,很少有时间研究一门,一般在网上复制代码是从来不留言的,不过自从昨天看了你的博客以后,受益匪浅也被也这种无私敬业感动了,以后多多指教哦,我能帮你的也会竭尽全力的,谢谢你的代码,研究中。