AlertBox 弹出层信息提示框效果实现步骤


Posted in Javascript onOctober 11, 2010

在仿Lightbox效果中,已经基本实现了这个效果,这次主要改进了ie6在fixed时的抖动问题。
此外,还增加了一个用来兼容ie6的fixed的方法,覆盖层也重新“包装”,程序也改成组件的结构。
兼容:ie6/7/8, firefox 3.6.8, opera 10.6, safari 5.0.1, chrome 5.0

效果预览 http://demo.3water.com/js/AlertBox/index.htm

程序说明

【实现原理】

弹出层的基本原理在仿Lightbox效果中已经说的差不多了。
关键的地方就是定位,一般相对文档的定位用absolute就行了。
要随屏移动,即相对窗口定位,就用fixed定位。
这些实现起来都很简单,除了不支持fixed的ie6。

【兼容ie6的fixed】

由于ie6本身不支持fixed定位,只能模拟或取巧来间接实现。
最原始的方法是在window的scroll事件中不断修正弹出层的位置。
后来有人发现还可以通过reflow“离奇”地实现。
但以上方法都有一个缺陷,滚动时弹出层会“发抖”,很不舒服(可以用缓动等来改善)。

想要不发抖,可以通过html和css的巧妙应用来实现,具体参考14px的介绍。 
原理是用一个容器代替body,然后对不会动的body绝对定位。
看来很完美,但有一个致命的问题,这个方法需要修改html结构,会影响到相关的一些东西,例如window的scroll事件等。

程序中用了另一个方法,通过body的背景和expression来实现,下面是一个兼容的fixed效果:

<!DOCTYPE html> 
<html> 
<head> 
<style> 
body { 
_background: url(about:blank) fixed; 
} 
.fixable { 
position:fixed; 
top:100px; 
_position:absolute; 
_top:expression((document).documentElement.scrollTop+100); 
} 
</style> 
</head> 
<body style="height:1500px;"> 
<div class="fixable">fixable</div> 
</body> 
</html>

相比前面的方法,这个是比较完美的了,但也有一些问题,例如body的背景只能用fixed,使用expression资源消耗相对较大。
更大的问题是不能实现用百分比值或right/bottom来定位。
为了解决这个问题,程序使用了一个定位层,这个层用上面的方法实现fixed定位,尺寸跟窗口大小一样,并且位置重合,那么只要用一般的定位方法相对这个层定位,就能达到相对窗口定位的效果了。

兼容程序主要在RepairFixed对象中,首先设置body背景:

if (body.currentStyle.backgroundAttachment !== "fixed") { 
if (body.currentStyle.backgroundImage === "none") { 
body.runtimeStyle.backgroundRepeat = "no-repeat"; 
body.runtimeStyle.backgroundImage = "url(about:blank)"; 
} 
body.runtimeStyle.backgroundAttachment = "fixed"; 
}

再创建定位层:
layer = document.createElement("<div style='position:absolute;border:0;padding:0;margin:0;overflow:hidden;background:transparent;top:expression((document).documentElement.scrollTop);left:expression((document).documentElement.scrollLeft);width:expression((document).documentElement.clientWidth);height:expression((document).documentElement.clientHeight);display:block;'>");

定位层还要设置"overflow:hidden",好处是不会因弹出层在document原来的范围外而自动扩大document。
ie6测试以下代码,document会随着下滚而不断扩大:
<!DOCTYPE html> 
<html> 
<head> 
<style> 
body { 
_background: url(about:blank) fixed; 
} 
.fixable { 
position:absolute; 
top:expression((document).documentElement.scrollTop+(document).documentElement.clientHeight); 
} 
</style> 
</head> 
<body> 
<div class="fixable">fixable</div> 
</body> 
</html>

加上"overflow:hidden"就可以防止这种情况。

然后弹出层通过append方法修改为"absolute"定位,并插入到这个定位层,这样就能实现fixed效果了。

由于这个定位层比较耗资源,所以在有元素插入时才会插到body中。
在不需要fixed的时候,要用remove方法从定位层中移除,当定位层内没有需要定位元素就会自动从body移除。
ps:隐藏的话expression还会继续执行,要移出文档才行。

【居中效果】

加入居中扩展程序,并且设置center为true,就会自动相对窗口居中。
居中的原理跟仿Lightbox效果是一样的,通过设置负的元素尺寸一半的margin和"50%"的top/left来居中。
要注意的是不是使用fixed定位时,计算需要加上scrollTop/scrollLeft。

【覆盖层】

在仿Lightbox效果中,ie6的覆盖层是通过创建一个覆盖整个页面的层来做的。
使用新的兼容fixed方法后,就不用另外做兼容,按照fixed的效果做就行了。
覆盖层是由AlertBox扩展而来,它其实就是一个大小跟窗口一样,并且跟窗口重合的弹出层。
由于覆盖层一般只需要定义一个就行了,这里把它做成一个OverLay对象,使用时直接调用它的show和close方法。

【遮盖select】

在仿Lightbox效果中介绍过两种遮盖select的方法:隐藏和iframe。
程序是通过iframe来遮盖的,放在ie6的兼容扩展程序中。
在iframe定位时要注意,要定位到弹出层的负的clientTop/clientLeft,这样才能保证边框不会被遮住。

使用技巧

【定位】

除了居中,程序会按照弹出层本身的定位样式来显示。
不是fixed定位时要注意,在ie6是相对当前窗口来定位的,其他都是相对第一屏窗口来定位的。
还要注意,必须声明DOCTYPE,才能正确定位。
程序为了尽量通用,降低了效率(用了4个expression),所以最好还是根据实际情况自己来调整。
ps:需要像定位提示效果那样预设定位的话,可以自行扩展。

【锁定键盘】

使用覆盖层时,为了防止用户通过键盘操作页面,可以在document的keydown中执行preventDefault来禁用。
如果弹出层需要正常操作,只要在弹出层的keydown中执行stopPropagation就行了。

【拖动弹窗】

这里只是简单的加上拖动功能,要注意的是fixed定位时,计算拖动的参考对象是不同的。
更详细的拖动介绍可以看看这个拖动效果。

使用说明

实例化时,必须有弹出层作为参数:

new AlertBox("idBox");

可选参数用来设置程序的默认属性,包括:
属性:    默认值//说明
fixed:  false,//是否固定定位
zIndex:  1000,//层叠数
onShow:  $$.emptyFunction,//显示时执行
onClose: $$.emptyFunction//关闭时执行

还提供了以下方法:
show:显示弹出层;
close:隐藏弹出层;
dispose:销毁程序。

加入兼容ie6扩展程序后,会自动修正ie6的fixed问题,可根据fixSelect属性设置是否修正select遮盖bug,默认是。
加入居中扩展程序后,可根据center属性设置是否居中,默认否。

RepairFixed修正fixed对象,可独立使用,有append和remove方法添加和移除需要fixed的元素,只能在ie6使用。
OverLay覆盖层对象,有如下属性:
属性:    默认值//说明
"color": "#fff",//背景色
"opacity": .5,//透明度(0-1)
"zIndex": 100,//层叠值
还有show和close方法显示和隐藏覆盖层。

打包下载地址

Javascript 相关文章推荐
改善你的jQuery的25个步骤 千倍级效率提升
Feb 11 Javascript
基于jQuery的输入框无值自动显示指定数据的实现代码
Jan 24 Javascript
html dom节点操作(获取/修改/添加或删除)
Jan 23 Javascript
浅析AngularJs HTTP响应拦截器
Dec 28 Javascript
jquery对所有input type=text的控件赋值实现方法
Dec 02 Javascript
js实现截图保存图片功能的代码示例
Feb 16 Javascript
jquery操作ul的一些操作笔记整理(干货)
Aug 31 jQuery
浅谈KOA2 Restful方式路由初探
Mar 14 Javascript
使用webpack搭建vue项目实现脚手架功能
Mar 15 Javascript
详解关于React-Router4.0跳转不置顶解决方案
May 10 Javascript
ant-design表单处理和常用方法及自定义验证操作
Oct 27 Javascript
浅谈JS的二进制家族
May 09 Javascript
基于jQuery的实现简单的分页控件
Oct 10 #Javascript
JQuery的Alert消息框插件使用介绍
Oct 09 #Javascript
Tips 带三角可关闭的文字提示
Oct 06 #Javascript
从零开始学习jQuery (二) 万能的选择器
Oct 01 #Javascript
fancybox1.3.1 基于Jquery的插件在IE中图片显示问题
Oct 01 #Javascript
客户端 使用XML DOM加载json数据的方法
Sep 28 #Javascript
jquery选择器(常用选择器说明)
Sep 28 #Javascript
You might like
Smarty+QUICKFORM小小演示
2007/02/25 PHP
Discuz Uchome ajaxpost小技巧
2011/01/04 PHP
php中显示数组与对象的实现代码
2011/04/18 PHP
php Smarty初体验二 获取配置信息
2011/08/08 PHP
input file获得文件根目录简单实现
2013/04/26 PHP
php 备份数据库代码(生成word,excel,json,xml,sql)
2013/06/23 PHP
编译PHP报错configure error Cannot find libmysqlclient under usr的解决方法
2014/06/27 PHP
PHP图片自动裁切应付不同尺寸的显示
2014/10/16 PHP
php+js实现百度地图多点标注的方法
2016/11/30 PHP
JS实现浏览器菜单命令
2006/09/05 Javascript
javascript 屏蔽鼠标键盘的几段代码
2008/01/02 Javascript
JavaScript Event学习第九章 鼠标事件
2010/02/08 Javascript
node在两个div之间移动,用ztree实现
2013/03/06 Javascript
JS获取html对象的几种方式介绍
2013/12/05 Javascript
javascript去除字符串中所有标点符号和提取纯文本的正则
2014/06/07 Javascript
Bootstrap CDN和本地化环境搭建
2016/10/26 Javascript
javascript入门之数组[新手必看]
2016/11/21 Javascript
浅谈React中组件间抽象
2018/01/27 Javascript
小程序的上传文件接口的注意要点解析
2019/09/17 Javascript
JQuery插件tablesorter表格排序实现过程解析
2020/05/28 jQuery
使用卷积神经网络(CNN)做人脸识别的示例代码
2020/03/27 Python
PyQt5实现仿QQ贴边隐藏功能的实例代码
2020/05/24 Python
Python机器学习工具scikit-learn的使用笔记
2021/01/28 Python
使用CSS3实现多列布局与多背景的技巧
2016/02/29 HTML / CSS
家庭睡衣和家庭用品:Little Blue House
2018/03/18 全球购物
世界上最大的冷却器制造商:Igloo Coolers
2019/07/23 全球购物
实习期自我鉴定
2013/10/11 职场文书
办公室前台的岗位职责
2013/12/20 职场文书
浙江文明网签名寄语
2014/01/18 职场文书
村主任个人对照检查材料
2014/10/01 职场文书
运动会广播稿200字
2014/10/18 职场文书
2016年教师师德师风心得体会
2016/01/12 职场文书
股东协议书范本2016
2016/03/21 职场文书
CentOS MySql8 远程连接实战
2022/04/19 MySQL
vue3.0 数字翻牌组件的使用方法详解
2022/04/20 Vue.js
JS class语法糖的深入剖析
2022/07/07 Javascript