html JS弹出层

最近要用到页面弹出层的效果,网上搜了一个,找到一个比较好的,记下来一遍以后参考,同时这么好的东西跟大家分享下。


<!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>
    <title>可拖动的弹出框</title>
    <meta http-equiv="Content-Type" content="text/html; charset=gb2312"/>
    <style type="text/css">
        body{margin:0}
        #popBox
        {
            width:350px;
            border:1px solid #cfcfcf;
            box-shadow:2px 3px 0 rgba(190,190,190,0.3);
            text-align:center;
            padding-bottom:20px;
            background-color: #fff;
            z-index: 101;
        }
        #popBox h3
        {
            height:30px;
            line-height:30px;
            font-size:14px;
            text-align: left;
            margin:0 0 20px 0;
            background-color:#62e580;
            color:#fff;
            border-bottom: 1px solid #cfcfcf;
            padding-left:15px;
            cursor:move;
        }
    </style>
</head>
<body>
ddddddddddddddddddddddddddddddddddddddd <select><option>iframe</option></select>
<input id="btn" type="button" value="点击显示登录框" style="margin-top: 300px">
<div id="range" style="width:500px; height:500px; background: teal"></div>
<div id="popBox">
    <h3 id="handle">登录</h3>
    <input id='ok' type="button" value="确认" />
    <input id='cancel' type="button" value="取消" />
</div>


<script type="text/javascript">
    if(!Function.prototype.bind) {
        Function.prototype.bind = function(o,args) {
            var _self = this;
            return function() {
                return _self.apply(o,[].concat(args));
            };
        };
    }
    var EventUtil = {
        _$:function(id) {
            return typeof id === 'string' ? document.getElementById(id) : id;
        },
        addEvent:function(el,type,handler) {
            return el.addEventListener ? el.addEventListener(type,handler,false) : el.attachEvent('on'+type,handler);
        },
        removeEvent:function(el,type,handler) {
            return el.removeEventListener ? el.removeEventListener(type,handler,false) : el.detachEvent('on'+type,handler);
        },
        getViewPort:function(w) {//获取视窗宽度和高度
            //使用指定的窗口,如果缺省则为当前窗口
            w = w || window;
            /*
             *当没有滚动条时,document.documentElement.clientWidth和window.innerWidth的值是一样的
             *出现滚动条时,前者的值比后者的小,差即为滚动条所占的宽度,做遮罩层或弹出层时,前者更为精确
             */
            //IE8及以下版本的IE系列未实现该方法
//            if(w.innerWidth != null) {
//                return {
//                    w:w.innerWidth,
//                    h:w.innerHeight
//                };
//            }
            var d = w.document;
            //IE标准模式,即声明了xhtml1.0头
            if(document.compatMode == 'CSS1Compat') {
                return {
                    w:d.documentElement.clientWidth,
                    h:d.documentElement.clientHeight,
                    sw:d.documentElement.scrollWidth,
                    sh:d.documentElement.scrollHeight
                };
            }
            //怪异模式(Quirks),未声明DOCTYPE
            return {
                w:d.body.clientWidth,
                h:d.body.clientHeight,
                sw:d.body.scrollWidth,
                sh:d.body.scrollHeight
            };
        },
        getScrollOffset:function(w) {//获取滚动位置
            //使用指定的窗口,如果缺省则为当前窗口
            w = w || window;
            //IE8及以下版本的IE系列未实现该方法
            if(w.pageXOffset != null) {
                return {
                    x:w.pageXOffset,
                    y:w.pageYOffset
                };
            }
            var d = w.document;
            //IE标准模式,即声明了xhtml1.0头
            if(document.compatMode == 'CSS1Compat') {
                return {
                    x:d.documentElement.scrollLeft,
                    y:d.documentElement.scrollTop
                };
            }
            //怪异模式(Quirks),未声明DOCTYPE
            return {
                x:d.body.scrollLeft,
                y:d.body.scrollTop
            }
        },
        getStyle:function(el,cName) {
            return el.currentStyle ? el.currentStyle[cName] : document.defaultView.getComputedStyle(el,null)[cName];
        },
        getBroswersVer: {
            isIE: /msie/i.test(navigator.userAgent) && !window.opera,
            isIE6: /msie 6/i.test(navigator.userAgent) && !window.opera,
            isChrome: /chrome/i.test(navigator.userAgent),
            isOpera:!!window.opera
        },
        getEvent:function(e) {
            return e || window.event;
        },
        preventDefault:function(e) {
            e = e || window.event;
            return e.preventDefault ? e.preventDefault() : e.returnValue = false;
        },
        setOpacity:function(el,level) {
            return el.filters ? (el.style.filter = 'alpha(opacity ='+level+')') : (el.style.opacity = level/100);
        },
        fadeIn:function(params) {
            params = params || {};
            var el = params.el || null,
                speed = params.speed || 20,     //淡入动画进行的速度
                level = params.level || 100,    //如果没有指定,则淡入透明度至100
                initOpacity = params.initOpacity || 0,  //开始动画时元素的透明度,如果没有则设为0
                elStyle = el.style,
                step = initOpacity;           //透明度每次改变的增量
            elStyle.display = 'block';
            (function() {
                EventUtil.setOpacity(el,step);
                step += 5;
                (step <= level) && setTimeout(arguments.callee,speed);
            })();
        },
        fadeOut:function(params) {
            params = params || {};
            var el = params.el || null,
                speed = params.speed || 20,       //淡出动画进行的速度
                level = params.level || 0,        //如果没有指定,则淡出透明度至0,然后隐藏该元素
                initOpacity = params.initOpacity || 100,  //开始动画时元素的透明度,如果没有则设为100
                elStyle = el.style,
                step = initOpacity;
            (function() {
                EventUtil.setOpacity(el,step);
                step -= 5;
                ((step >= level) && setTimeout(arguments.callee,speed)) || (elStyle.display = 'none');
            })();
        }
    };

    //为获取对象ID的方法定义快捷方式
    var $ = EventUtil._$,
        isIE6 = EventUtil.getBroswersVer.isIE6,
        isIE = EventUtil.getBroswersVer.isIE,
        isOpera = EventUtil.getBroswersVer.isOpera;

    /*
     * 弹出框构造函数
     */
    function PopUp() {
        return this.init.apply(this,arguments);
    }
    PopUp.prototype = {
        init:function(params) {
            params = params || {};
            //获取弹出框对象,如果没有指定则使用默认
            this.pop = $(params.id) || $('popBox');
            //获取拖动手柄,如未指定则将其设置为整个弹出框
            this.handle = $('handle') || this.pop;
            var pStyle = this.pop.style;
            //弹出框是否跟随滚动条滚动,默认为允许
            this.isScroll = params.isScroll || 'enabled';
            //跟随窗口滚动时非IE6浏览器可以用fixed,不跟随则需要设为absolute
            //Opera是一个特殊情况,它在设置为fixed时和Firefox、Chrome浏览器的行为不一致
            //具体为ff、chrome在fixed计算坐标都是相对窗口的,但Opera需要考虑滚动条
            //为了方法通用,故将Opera与IE6归为一类
            this.isScroll == 'enabled' ?
                    ((isIE6 || isOpera) ? pStyle.position = 'absolute' : pStyle.position = 'fixed') :
                    pStyle.position ='absolute';

            //是否需要创建遮罩层,默认为创建
            this.enableShadow = params.enableShadow == 'disabled' ? false : new Shadow();
            //是否启用拖放,默认为启用
            this.enableDrag = params.enableDrag == 'disabled' ? false : new
                    Drag({
                        target:this.pop,
                        isScroll:params.isScroll || 'enabled'
                        //sMode:'horizontal'
//                        range:{
//                            minLeft:$('range').getBoundingClientRect().left,
//                            maxLeft:$('range').getBoundingClientRect().right - this.pop.offsetWidth,
//                            minTop:$('range').getBoundingClientRect().top,
//                            maxTop:$('range').getBoundingClientRect().bottom - this.pop.offsetHeight
//                        }
                    });
            //如果禁用拖放需要把拖动手柄的鼠标样式设为默认
            if(this.enableDrag == false) this.handle.style.cursor = 'default';
            
            //获取弹出框的宽度和高度
            var s = this.pop.getBoundingClientRect();
            //由于IE的getBoundingClientRect()方法没有width和height属性,故取右边距和左边距之差来代替width,高度也一样
            this.w = s.width || s.right - s.left;
            this.h = s.height || s.bottom - s.top;
            pStyle.display = 'none';
        },
        setPosition:function(params) {
            params = params || {};
            var pStyle = this.pop.style;

            //如果传入的参数中指定了坐标位置,则将值赋给弹出框
            if(params.x != undefined && params.y != undefined) {
                pStyle.left = params.x + 'px';
                pStyle.top = params.y + 'px';
                return;  //返回
            }
            //如果未指定坐标,则弹出框屏幕居中显示
            //IE6、Opera以及弹出框禁止跟随滚动条时使用的定位方式是absolute,需要加上滚动距离
            var x = (EventUtil.getViewPort().w - this.w) / 2 + (isIE6 || isOpera || this.isScroll == 'disabled' ?
                    EventUtil.getScrollOffset().x : 0);
                y = (EventUtil.getViewPort().h - this.h) / 2 + (isIE6 || isOpera || this.isScroll == 'disabled' ?
                        EventUtil.getScrollOffset().y : 0);
            pStyle.left = x + 'px';
            pStyle.top = y + 'px';
        },
        show:function(params) {
            params = params || {};
            //淡入弹出框
            EventUtil.fadeIn({el:this.pop});
            //显示遮罩层
            this.enableShadow && this.enableShadow.show();
            //弹出框定位
            this.setPosition(params);
        },
        hide:function() {
            EventUtil.fadeOut({el:this.pop});
            this.enableShadow && this.enableShadow.hide();
        }
    };

    /*
     * 拖放构造函数
     */
    function Drag() {
        return this.init.apply(this,arguments);
    }
    Drag.prototype = {
        init:function(params) {
            params = params || {};
            var _self = this;
            //获取拖放元素
            this.dragTarget = params.target || $('popBox');
            //拖动手柄
            this.handle = $('handle');
            //范围限定,如果传入该参数则弹出框将在指定范围内可拖动
            this.range = params.range || {};
            //是否跟随滚动条滚动
            this.isScroll = params.isScroll || 'enabled';
            var s = this.dragTarget.getBoundingClientRect();
            this.w = s.width || s.right - s.left;
            this.h = s.height || s.bottom - s.top;
            //水平锁定或垂直锁定
            this.sMode = params.sMode || null;
            //元素在移动时触发的事件
            this.moveHandler = function(e) {
                _self.move(e);
            };
            //在释放鼠标时触发的事件
            this.upHandler = function() {
                _self.dragStop();
            };
            //按下鼠标时拖放开始
            EventUtil.addEvent(this.handle,'mousedown',function(e) {
                _self.dragStart(e);
            });
        },
        dragStart:function(e) {//开始拖放
            e = e || window.event;
            var _self = this,
                target = this.dragTarget,
                isPosAbs = target.style.position == 'absolute';
            EventUtil.preventDefault(e);
            //拖放开始时设置透明度为50
            EventUtil.setOpacity(this.dragTarget,50);

            //当鼠标移出窗口或切换视窗时仍能捕获事件
            (target.setCapture && isIE) && target.setCapture(true);

            //清除选中文本,前面是IE特有的方法
            (document.selection && document.selection.empty) ? document.selection.empty() :
                    window.getSelection().removeAllRanges();

            //保存鼠标相对拖放元素的坐标和当前元素可移动的最大宽高度
            this.offset = {//layerX(Firefox)、offsetX(IE、Opera)
                x:e.clientX - target.getBoundingClientRect().left,
                y:e.clientY - target.getBoundingClientRect().top,
                //fixed定位取的是相对于当前窗口的位移,不需要加上滚动值,而absolute定位需要加上滚动的值
                maxX:this.range.maxLeft - (isPosAbs ? 0 : EventUtil.getScrollOffset().x) || EventUtil.getViewPort().w -
                    this.w + (target.style.position == 'absolute' ? EventUtil.getScrollOffset().x : 0),
                maxY:this.range.maxTop - (isPosAbs ? 0 : EventUtil.getScrollOffset().y) || EventUtil.getViewPort().h -
                        this.h + ((target.style.position == 'absolute') ? EventUtil.getScrollOffset().y : 0)
            };
            //注册鼠标移动和释放鼠标事件
            EventUtil.addEvent(document,'mousemove',this.moveHandler);
            EventUtil.addEvent(document,'mouseup',this.upHandler);
        },
        move:function(e) {
            e = e || window.event;
            //阻止浏览器默认事件,IE8有滚动条随拖放滚动和默认选中文字的默认行为
            EventUtil.preventDefault(e);
            //通过鼠标当前位置坐标减去相对位置坐标获得元素的left和top值
            var sx = EventUtil.getScrollOffset().x,     //保存当前滚动宽度
                sy = EventUtil.getScrollOffset().y,     //保存当前滚动高度
                //保存元素在页面内的坐标
                x = e.clientX - this.offset.x + (isIE6 || isOpera || this.isScroll == 'disabled' ? sx : 0),
                y = e.clientY - this.offset.y + (isIE6 || isOpera || this.isScroll == 'disabled' ? sy : 0),
                //保存元素可以移动的最大横坐标和纵坐标
                maxX = this.offset.maxX,
                maxY = this.offset.maxY;
            //设置元素的坐标并防止弹出框位置超出指定范围
            if(isIE6 || isOpera || this.isScroll == 'disabled') {//如果是IE6、Opera或者设置了禁止跟随浏览器滚动
                (this.sMode == 'horizontal' || this.sMode == null) && (this.dragTarget.style.left = Math.min(maxX, x
                        <= (this.range.minLeft || sx) ? (this.range.minLeft || sx) : x) +'px');
                (this.sMode == 'vertical' || this.sMode == null) && (this.dragTarget.style.top = Math.min(maxY, y <=
                        (this.range.minTop || sy) ? (this.range.minTop || sy) : y) + 'px');
                return;
            }

            (this.sMode == 'horizontal' || this.sMode == null) && (this.dragTarget.style.left = Math.min(maxX,x <=
                    (this.range.minLeft-sx || 0) ? (this.range.minLeft-sx || 0) : x) + 'px');
            (this.sMode == 'vertical' || this.sMode == null) && (this.dragTarget.style.top = Math.min(maxY,y <=
                    (this.range.minTop-sy || 0) ? (this.range.minTop-sy || 0) : y) + 'px');

        },
        dragStop:function() {//停止拖放
            EventUtil.setOpacity(this.dragTarget,100);
            //停止窗口捕获
            (this.dragTarget.releaseCapture && isIE) && this.dragTarget.releaseCapture();
            EventUtil.removeEvent(document,'mousemove',this.moveHandler);
            EventUtil.removeEvent(document,'mouseup',this.upHandler);
        }
    };

    /*
     * 遮罩层构造函数
     */
    function Shadow() {
        return this.init.apply(this,arguments);
    }
    Shadow.prototype = {
        init:function() {},
        create:function(params) {//创建遮罩层
            params = params || {};
            //如果遮罩层已存在,返回
            if(this.shadow) return;
            var c = document.createElement('div'),
                s = c.style;
            //为遮罩层定义样式
            c.id = 'shadow';
            s.backgroundColor = params.bgColor || '#000';
            s.position = isIE6 ? 'absolute' : 'fixed';
            s.left = s.top = 0;
            //设置遮罩层的宽高
            this.setProperty(c);
            s.zIndex = 100;
            s.display = 'none';
            //为防止IE6中止操作的问题,用insertBefore代替appendChild方法
            document.body.insertBefore(c,document.body.childNodes[0]);
            //将遮罩层保存到this.shadow
            this.shadow = c;
            //IE6下有遮罩层不能遮盖select元素的bug,通过创建一个iframe来解决
            if(isIE6 && !this.fixedIframe) {
                var iframe = document.createElement('iframe'),
                    iStyle = iframe.style;
                iStyle.position = 'absolute';
                iStyle.left = iStyle.top = 0;
                iStyle.zIndex = 1;
                iStyle.src = 'about:blank';
                iStyle.filter = 'alpha(opacity=0)';
                //设置iframe的宽高
                this.setProperty(iframe);
                document.body.insertBefore(iframe,document.body.childNodes[0]);
                this.fixedIframe = iframe;
            }
            //返回创建的遮罩层
            return c;
        },
        setProperty:function(el) {
            var s = el.style;
            //比较clientWidth(clientHeight)与scrollWidth(scrollHeight)的大小,取其中较大的一个作为宽高度
            s.width = Math.max(EventUtil.getViewPort().w,EventUtil.getViewPort().sw) + 'px';
            s.height = Math.max(EventUtil.getViewPort().h,EventUtil.getViewPort().sh) + 'px';
        },
        show:function(params) {
            params = params || {};
            EventUtil.fadeIn({
                el:this.shadow || this.create(params), //如果不存在则创建
                level:30    //淡入到30的透明度
            });
            //如果存在iframe,与遮罩层一并显示
            this.fixedIframe && (this.fixedIframe.style.display = 'block');
        },
        hide:function() {
            EventUtil.fadeOut({
                el:this.shadow || this.create(),
                initOpacity:30
            });
            //如果存在iframe,与遮罩层一并隐藏
            this.fixedIframe && (this.fixedIframe.style.display = 'none');
        }
    };

    //初始化弹出框
    var p = new PopUp({
        //isScroll:'disabled'
        //enableDrag:'disabled'
        //enableShadow:'disabled'
    });

    //缩放窗口时重新定位弹出框及遮罩层的宽度和高度
    EventUtil.addEvent(window,'resize', function() {
        p.setPosition();
        //如果开启遮罩层,遮罩层元素存在,则重新定位遮罩层
        p.enableShadow && p.enableShadow.shadow && p.enableShadow.setProperty(p.enableShadow.shadow);
    });
    EventUtil.addEvent($('btn'),'click', function() {
        p.show({//定义坐标,如果缺省则居中显示
//            x:100,
//            y:100
        });
    });
    EventUtil.addEvent($('ok'),'click', p.hide.bind(p));
    EventUtil.addEvent($('cancel'),'click', p.hide.bind(p));

    //当按下ESC键时关闭弹出框
//    EventUtil.addEvent(document,'keyup',function(e) {
//        e = e || window.event;
//        e.keyCode == 27 && p.hide();
//    });

    EventUtil.addEvent(window,'load',function() {
        if((isIE6 || isOpera) && p.isScroll != null && p.isScroll == 'enabled') {
            EventUtil.addEvent(window,'scroll', function() {
                setTimeout(function() {
                    p.setPosition();
                },100);
            });
        }
    });
</script>
</body>
</html>

原文地址: http://www.cnblogs.com/undefined000/archive/2012/08/13/2635917.html


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值