• 弹窗层效果的实现(非jQuery实现)


    要想实现弹窗的效果,首先应该创建一个覆盖层maskLayer,以及一个显示层presentLayer。

    其次,每次弹窗时(除首次弹窗外),maskLayer的显示以及隐藏不应该导致文档流的reflow,但是repaint不可避免。所以对于maskLayer,用以display:absolute;

    最为关键的就是显示层的定位居中显示,根据maskLayer的高度和宽度计算出显示层的位置。

    另外,为了多样性的支持弹窗的内容,该实现也提供了ajax抓取的相应功能,但具体并未测试,仓促做出的简单测试也并不完美。

    为了节约空间大小,直接将该页面呈现。

    <!DOCTYPE html>
    <html>
    <head lang="en">
        <meta charset="UTF-8">
        <title></title>
        <style>
            html,body{margin: 0;padding: 0;overflow: hidden;}
            #maskLayer{position: absolute;z-index: 1000;}
            #presentLayer{position: absolute;z-index: 1500;border: 10px solid #e3e3e3;background: url(img/preload.gif) center center no-repeat;}
        </style>
    </head>
    <body>
        <img id="test" src="http://image.zhangxinxu.com/image/study/s/mm10.jpg" width="200" height="200">
        <script>
            document.querySelector('#test').addEventListener('click',function(){
                var img = '<img src="http://image.zhangxinxu.com/image/study/s/mm10.jpg" width="640" height="466">'
                var clk = "<object classid='clsid:D27CDB6E-AE6D-11cf-96B8-444553540000' width='550' height='400'><param name='movie' value='img/as3_clock_2.swf' /><param name='quality' value='high' /><param name='wmode' value='opaque' /><embed height='400' width='550'  src='img/as3_clock_2.swf' type='application/x-shockwave-flash'></embed></object>";
                var con = '3s后即将关闭';
                Popup.u.show(clk,0,0,0,1);
            },false)
        </script>
        <script>
            (function(window){
                function get(id){
                    return document.getElementById(id);
                }
                if(!window.Popup) var Popup = {};
                window.Popup = Popup;
                Popup.u = function(){
                    var maskLayer,presentLayer,contentLayer,
                            scontent,sisAjax,swidth,sheight,sauto;
                    var f = false
                    return {
                        /**
                         * @param content
                         * @param isAjax
                         * @param width
                         * @param height
                         * @param auto  自适应宽度高度
                         * @param timeout
                         */
                        show: function(content,isAjax,width,height,auto,timeout){
                            var that = this;
                            if(!maskLayer){
                                maskLayer = document.createElement('div');
                                maskLayer.id = 'maskLayer'
                                presentLayer = document.createElement('div');
                                presentLayer.id = 'presentLayer';
                                presentLayer.style.position = 'absolute';
                                contentLayer = document.createElement('div');
                                contentLayer.id = 'contentLayer';
                                contentLayer.style.display = 'none';
                                maskLayer.style.position = 'absolute';
                                maskLayer.style.top = 0;
                                document.body.appendChild(maskLayer);
                                document.body.appendChild(presentLayer);
                                presentLayer.appendChild(contentLayer);
    
                                maskLayer.onclick = this.hide;
                                window.onresize = this.resize;
                            }
                            scontent = content;
                            sisAjax = isAjax;
                            swidth = width;
                            sheight = height;
                            sauto = auto;
    
                            this.spread();
                            this.preshow();
                            this.filter(maskLayer,80,3,1);
                            if (timeout)
                            setTimeout(that.hide,timeout * 1000);
                        },
                        load: function(content,isAjax,width,height,auto){
                            var that = this;
                            if(isAjax){
                                var xhr = that.ajax();
                                xhr.onreadystatechange = function(){
                                    if(xhr.readyState == 4){
                                        if(xhr.status >= 200 && xhr.status < 300 || xhr.status == 304){
                                            that.process(xhr.responseText,width,height,auto);
                                        }
                                    }
                                };
                                xhr.open('GET',content,true);
                                xhr.send(null);
                            }else{
                                that.process(content,width,height,auto);
                            }
                        },
                        hide: function(){
                            Popup.u.filter(presentLayer,0,5,-1);
                        },
                        process: function(content,width,height,auto){
                            if(auto){
                                if(!width && !height){
                                    var preW = parseInt(presentLayer.style.width),
                                            preH = parseInt(presentLayer.style.height);
                                    presentLayer.style.width = '';
                                    presentLayer.style.height = '';
                                    contentLayer.style.width = '';
                                    contentLayer.style.height = '';
                                    contentLayer.style.display = '';
                                    presentLayer.style.backgroundImage = 'none';
                                    contentLayer.innerHTML = content;
    
                                }else{
                                    presentLayer.style.width = width;
                                    presentLayer.style.height = height;
                                }
                                this.layout(preW,preH,width,height);
                            }
                        },
                        ajax: function(){
                            var that = this,fns;
                            fns = [function(){return new window.XMLHttpRequest();},function(){return new ActiveXObject('Msxml2.XMLHTTP')},
                            function(){return new ActiveXObject('Microsoft.XMLHTTP')}];
                                for(var i,len = fns.length;i<len;i++){
                                    try{
                                        new fns[i]();
                                        that.ajax = fns[i];
                                        break;
                                    }catch (e){}
                                }
                            return ajax();
                        },
                        resize: function(){
                            Popup.u.position();
                            Popup.u.spread();
                        },
                        // presentLayer 初始显示
                        preshow: function(bgimg){
                            var clientHeight = Popup.p.clientHeight(),clientWidth = Popup.p.clientWidth(),
                                    setTop,setLeft;
                            bgimg = bgimg?bgimg:'';
                            presentLayer.style.display = 'none';
                            presentLayer.style.backgroundColor = '#fff';
                            presentLayer.style.backgroundImage = bgimg;
                            presentLayer.style.width = '100px';
                            presentLayer.style.height = '100px';
                            setTop = (clientHeight - 100) / 2;
                            setLeft = (clientWidth - 100) /2;
                            setTop = setTop < 20 ? 20 : setTop;
                            presentLayer.style.left = setLeft + 'px';
                            presentLayer.style.top = setTop + 'px';
                            presentLayer.style.display = '';
                            return;
                        },
                        /**
                         * @param bgimg
                         * 遮盖层展开,设置height width
                        **/
                        spread: function(bgimg){
                            bgimg = bgimg?bgimg:'';
                            maskLayer.style.backgroundColor = '#303030';
                            maskLayer.style.backgroundImage = bgimg;
                            maskLayer.style.width = Popup.p.pageWidth() + 'px';
                            maskLayer.style.height = Popup.p.pageHeight() + 'px';
                            return;
                        },
                        // 定位 presentLayer
                        position: function(){
                            var clientHeight = Popup.p.clientHeight(),
                                    clientWidth = Popup.p.clientWidth(),
                                    boxW,boxH,setLeft,setTop;
                            boxH = presentLayer.offsetHeight;
                            boxW = presentLayer.offsetWidth;
                            setTop = Math.abs(clientHeight - boxH) / 2;  console.log(setTop)
                            setLeft = Math.abs(clientWidth - boxW) /2;
                            setTop = setTop < 20 ? 20 : setTop;
                            presentLayer.style.left = setLeft + 'px';
                            presentLayer.style.top = setTop + 'px';
                            return ;
                        },
                        layout: function(preW,preH,width,height){  // 设定presentLayer 和 contentLayer的位置关系
                            var padding,margin,
                                    finW,finH,
                                    that = this,
                                    factorW,factorH,
                                    curW = preW,curH = preH,
                                    timeid;
                            /*console.log('presentLayer:'+presentLayer.offsetWidth+" "+presentLayer.offsetHeight)
                            console.log('contentLayer:'+contentLayer.offsetWidth+" "+contentLayer.offsetHeight)
                            */
                            if(!width && !height){
                                finW = contentLayer.offsetWidth;
                                finH = contentLayer.offsetHeight;
                            }else{
                                finW = width;
                                finH = height;
                            }
    
                            factorW = finW > preW ? 1 : -1;
                            factorH = finH > preH ? 1 : -1;
                            presentLayer.style.paddingBottom = '10px';
                            presentLayer.style.paddingTop = '10px';
                            presentLayer.style.paddingLeft = '10px';
                            presentLayer.style.paddingRight = '10px';
                            contentLayer.style.display = '';
    
                            function recurse(){
                                if(curW == finW){
                                    if(curH == finH){
                                        clearInterval(timeid);
                                        that.position();
                                        contentLayer.style.display = '';
                                        return;
                                    }
                                }else{
                                    curW += Math.ceil(Math.abs(finW - curW) / 3) * factorW;
                                    presentLayer.style.width = curW + 'px';
                                }
    
                                if(curH == finH){
                                    if(curW == finW){
                                        clearInterval(timeid);
                                        that.position();
                                        contentLayer.style.display = '';
                                        return;
                                    }
                                }else{
                                    curH += Math.ceil(Math.abs(finH - curH) / 3) * factorH;
                                    presentLayer.style.height = curH + 'px';
                                }
                                that.position();
                            }
                            timeid = setInterval(recurse,20);
                        },
                        /**
                         * @param el
                         * @param opacity
                         * @param factor  每次迭代所增减的因子
                         * @param iod 增减性,取值为正负1.  -1 则意味着透明度逐渐为零
                         */
                        filter: function(el,opacity,factor,iod){
                            if(el.uuid){
                                clearInterval(el.uuid);
                            }
    
                            var curVal = 0,that = this;
                            if(iod == -1){
                                curVal = el.style.opacity * 100;
                            }else{
                                el.style.opacity = 0;
                                el.style.filter = 'alpha(opacity=0)';
                            }
    
                            function recurse(){
                                if(curVal == opacity){
                                    clearInterval(el.uuid);
                                    el.uuid = null;
                                    if(iod == 1){ // 先显示maskLayer,然后显示presentLayer
                                        el.style.display = '';
                                        el === maskLayer ? that.filter(presentLayer,100,5,1) : that.load(scontent,sisAjax,swidth,sheight,sauto);
                                    }else{  // 先隐藏presentLayer
                                        el.style.display = 'none';
                                        if(el === presentLayer){
                                            el.style.width = el.style.height = 0;
                                        }
                                        el === presentLayer ? that.filter(maskLayer,0,3,-1):contentLayer.innerHTML = '';
                                    }
                                }else{
                                    curVal += Math.ceil(Math.abs(opacity - curVal) / factor) * iod;
                                    el.style.opacity = curVal / 100;
                                    el.style.filter = 'alpha(opacity=' + curVal + ')';
                                }
                            }
                            el.uuid = setInterval(recurse,20);
                        }
                    };
    
                }();
    
                Popup.p = function(){
                    var h = document.documentElement,b = document.body;
                    return {
                        pageWidth: function(){return Math.max(Math.max(h.scrollWidth, b.scrollWidth),Math.max(h.offsetWidth, b.offsetWidth))},
                        pageHeight: function(){return Math.max(Math.max(h.scrollHeight, b.scrollHeight),Math.max(h.offsetHeight, b.offsetHeight))},
                        clientWidth: function(){return window.innerWidth || h.clientWidth || b.clientWidth},
                        clientHeight: function(){return window.innerHeight || h.clientHeight || b.clientHeight}
                    }
                }();
            })(window);
    
        </script>
    </body>
    </html>
  • 相关阅读:
    函数length属性
    vue面试题
    ES6引进新的原始数据类型symbol使用及特性
    jq动画
    防抖和节流
    this指向
    前端:性能优化之回流和重绘
    react生命周期
    vue生命周期
    react-redux的实现原理
  • 原文地址:https://www.cnblogs.com/accordion/p/4092285.html
Copyright © 2020-2023  润新知