Welcome 微信登录

首页 / 脚本样式 / JavaScript / 原生javascript实现图片弹窗交互效果

【一】用var 声明多个变量,比每个变量都用var快多了
复制代码 代码如下:
var sScrollTop = document.body.scrollTop || document.documentElement.scrollTop,
    sWindow_h = document.documentElement.clientHeight,
    t_h = parseInt(this.getCss(this.getId("gy_photoBox_head"),"height")),
    hold_h = sWindow_h - t_h - 20,
    width = this.nImgWidth ,
    height = this.nImgHeight;

【二】Dom事件优化,在 window.onresize时,定义个定时器,setTimeout,可以防止事件频繁调用
复制代码 代码如下:
windowResize:function(){
            var _that = this,
                _timer = null;
            // 函数节流
            window.onresize = function(){
                clearTimeout(_timer);
                _timer = setTimeout(function(){
                    if( _that.tools.getId("gy_photoBox")){
                        _that.setBoxCss();
                    }
                },100);
            }       
        }

【三】图片加载的处理函数
复制代码 代码如下:
/*
        @ src [String] 图片的地址
        @ success [Function] 图片加载成功的回调函数
        @ error [Function] 图片加载失败的回调函数
        */
        imgLoading:function(opt){
            var _img = new Image(),
                _that = this;
            _img.onload = function(){
                _that.nImgWidth = this.width;
                _that.nImgHeight = this.height;
                if(typeof opt.success == "function"){
                    setTimeout(function(){
                        opt.success();
                    },300);
                }
            }
            _img.onerror = function(){
                if(typeof opt.error){
                    opt.error();
                }           
            }
            // 注意:要放在onload事件下面,否则ie会出现BUG
            _img.src = opt.src;
        }

源代码:
复制代码 代码如下:
/*
author:laoguoyong
*/
(function(){
    /* -------------------------简单的选择器-----------------------
    @ 参数 [string]
    ---------------------------------------
    ★-只支持以下选择-★
    @ 支持一级选择器:如"#id",".class","p"
    @ 支持后代选择,如 ".class p","body span"
    @ 支持子元素选择,如 ".class>p","body>span"
    ----------------------------------------
    @ return [Array]
    */
    var selector = function(str){
        // 定义元素数组
        var elem = [];
        /* 私有方法
        ------------------------*/
        //返回是id的元素
        function _getId(id){
            return document.getElementById(id);
        }
        //返回存在此类名的元素-元素
        function _getByClassName(className,parent){
            var class_array = [],
                node = parent != undefined&&parent.nodeType==1?parent.getElementsByTagName("*"):document.getElementsByTagName("*"),
                reg = new RegExp("(^|\s)"+className+"(\s|$)");
            for(var n=0,i=node.length;n<i;n++){
                if(reg.test(node[n].className)){
                    class_array.push(node[n]);
                }
            }
            return class_array;
        }
        //一级选择,如 "#id","p",".class"
        // return [Array]
        function _getDom(s){
            var array_elem = [];
            if (s.indexOf("#")==0){
                array_elem.push(_getId(s.slice(1)));
            }
            else if(s.indexOf(".")==0){
                array_elem = array_elem.concat(_getByClassName(s.slice(1)));
            }
            else{
                var tag = document.getElementsByTagName(s);
                for(var n=0,i=tag.length;n<i;n++){
                    array_elem.push(tag[n]);
                }
            }
            return array_elem;
        }
        /*
        @ arry_elm [Array] : 元素数组,如 [".demo","p"] ,选择的是.demo下面的p元素,至于是选择后代还是子代,请看第2个参数解释
        @ r [String] -可选(不传默认为选择后代): ">",是选择子代元素;
        --------------------------
        @ return [Array]
        */
        function _query(array_elem,r){
            var node = array_elem,
                type_name = node[0].match(/#/)?"id_"+node[0].slice(1):node[0].match(/./)?"className_"+node[0].slice(1):"tagName_"+node[0],
                child = _getDom(node[1]),
                type = type_name.split("_"),
                len = document.getElementsByTagName("*").length,
                reg = new RegExp("(^|\s)"+type[1]+"(\s|$)");;
            for(var i=0,j=child.length;i<j;i++){
                var par = child[i].parentNode;
                for(var n=0;n<len;n++){
                    if(par.nodeType == 9){
                        break;
                    }
                    if(reg.test(par[type[0]])){
                        elem.push(child[i]);
                        break;                   
                    }else{
                        if(r == ">") break;
                        par = par.parentNode;
                    }       
                }
            }
        }
        /* 接口
        -----------------------*/
        var elemStr = str.replace(/(^s+)|(s+$)/,"");
        if(document.querySelectorAll){
            var dom = document.querySelectorAll(elemStr);
            for(var n=0,len=dom.length;n<len;n++){
                elem.push(dom[n]);
            }
        }else{
            var    split = /[>s]/g.exec(elemStr);
            if(split){
                var node = elemStr.split(split[0]);
                _query(node,split[0]);
            }else{
                elem = elem.concat( _getDom(elemStr) );
            }
        }
        return elem;
    }
    /* 弹窗功能构造函数
    -----------------------*/
    function LGY_photoBox(option){
        this.opt = option;
        this.oTarget = typeof option.target == "object"?option.target:selector(option.target);
        if(!this.oTarget) return;
        this.nLen = this.oTarget.length; //总个数
        this.aBigimg_src = []; //大图数据数组
        this.aTitle = []; //标题数据数组
        this.nIndex = 0; //索引
        this.nImgWidth = 0; //动态获取图片的宽
        this.nImgHeight = 0; //动态获取图片的高
        this.nDelay = 0.2;
        this.intit();
    }
    LGY_photoBox.prototype = {
        intit:function(){
            var _that = this;
            this.getData();
            for(var n=0;n<this.nLen;n++){
                this.oTarget[n].index = n;
                this.oTarget[n].onclick = function(e){
                    _that.createCover();
                    var e = _that.tools.getEvent(e),
                        target = _that.tools.getTarget(e);
                    // 设置浏页面没有滚动条出现
                    _that.tools.setCss(document.documentElement,{"height":"100%","overflow-y":"hidden","overflow-x":"hidden"});
                    // 获取当时索引
                    _that.nIndex = this.index;
                    //首次判断
                    _that.firstLoad(_that.aBigimg_src[_that.nIndex],function(){
                        //插入结构
                         _that.createBoxDom();
                        //关闭
                        _that.tools.getId("gy_photoBox_close").onclick = function(){
                            _that.removeBox();                                   
                        }
                        // 判断左右按钮显示
                        _that.btnIsShow();   
                        // 上一张
                        _that.btnPrev();
                        // 下一张
                        _that.btnNext();
                        // 加载图片
                        _that.imgChange(_that.aBigimg_src[_that.nIndex]);
                    });
                    // 重置窗口大小
                    _that.windowResize();
                     // 键盘事件
                    _that.keyEvent();
                    //阻止跳转
                    return false;   
                }
            }
        },
        createBoxDom:function(){
            var doc = document,
                exHtml = "",
                boxHtml = doc.createElement("div");
            boxHtml.id = "gy_photoBox";
            doc.body.appendChild(boxHtml);
            if(typeof this.opt.appendHTML == "string"){
                exHtml = this.opt.appendHTML;
            }
            boxHtml.innerHTML = "<div id="gy_photoBox_prev"></div>"+
                            "<div id="gy_photoBox_next"></div>"+
                            "<span id="gy_photoBox_close"></span>"+
                            "<div id="gy_photoBox_head">"+exHtml+"</div>"+
                            "<div id="gy_photoBox_main">"+
                                "<img id="gy_photoBox_img_loading" src="http://www.pconline.com.cn/blank.gif" />"+
                                "<img id="gy_photoBox_img" />"+
                                "<div id="gy_photoBox_infor">"+
                                    "<span id="gy_photoBox_num">"+
                                        "<strong id="gy_photoBox_index"></strong>"+
                                        "/"+this.nLen+
                                    "</span>"+
                                    "<p id="gy_photoBox_title"></p>"+
                                "</div>"+
                            "</div>";
        },
        createCover:function(){
            // 创建覆盖层
            var    doc = document,
                coverHtml = doc.createElement("div");
                coverHtml.id = "gy_photoBox_cover";
            doc.body.appendChild(coverHtml);
            //设置覆盖层的样式
            this.tools.setCss(this.tools.getId("gy_photoBox_cover"),{"height":(doc.body.scrollTop || doc.documentElement.scrollTop)+(doc.documentElement.clientHeight)+"px"});
        },
        setBoxCss:function(){
            var    doc = document,
                nScrollTop = doc.body.scrollTop || doc.documentElement.scrollTop,
                nWindow_h = doc.documentElement.clientHeight,
                eBox_head_h = this.tools.getId("gy_photoBox_head").clientHeight,
                eBox = this.tools.getId("gy_photoBox"),
                eBoxPadding = 10,
                hold_h = nWindow_h - eBoxPadding - 50 - eBox_head_h,
                width = this.nImgWidth ,
                height = this.nImgHeight;
            // alert("nWindow_h:"+nWindow_h+"-"+"eBoxPadding:"+eBoxPadding+"-"+"eBox_head_h:"+eBox_head_h);
            // 图片大小超过可见范围,进行缩放
            if(this.nImgHeight>hold_h){
                height = hold_h,
                width = Math.ceil(this.nImgWidth*(height/this.nImgHeight));
            }
            //设置盒子在整个页面居中
            this.tools.setCss(eBox,{"width":width+"px",
                                    "height":eBox_head_h + height + "px",
                                    "margin-left":-(width+eBoxPadding)/2+"px",
                                    "top":nScrollTop+(nWindow_h-height-eBoxPadding)/2+"px"});
            this.tools.setCss(this.tools.getId("gy_photoBox_main"),{"width":width+"px","height":height + "px"});
            //设置覆盖层的样式
            this.tools.setCss(this.tools.getId("gy_photoBox_cover"),{"height":nScrollTop+doc.documentElement.clientHeight+"px"});
        },
        removeBox:function(){
            var doc = document;
            if(this.tools.getId("gy_photoBox")){
                doc.body.removeChild(this.tools.getId("gy_photoBox"));
            }
            if(this.tools.getId("gy_photoBox_cover")){
                document.body.removeChild(this.tools.getId("gy_photoBox_cover"));
            }
            this.tools.setCss(document.documentElement,{"height":"auto","overflow-y":"auto","_overflow-y":"scroll","overflow-x":"auto"});
        },
        getData:function(){
            for(var n=0;n<this.nLen;n++){
                var src = this.oTarget[n].getAttribute("href"),
                    title = this.oTarget[n].getAttribute("title");
                this.aBigimg_src.push(src);
                if(!title) title = "";
                this.aTitle.push(title);
            }
        },
        btnIsShow:function(){
            this.tools.setCss(this.tools.getId("gy_photoBox_prev"),{"display":"block"});
            this.tools.setCss(this.tools.getId("gy_photoBox_next"),{"display":"block"});
            if(this.nIndex == 0) this.tools.setCss(this.tools.getId("gy_photoBox_prev"),{"display":"none"});
            if(this.nIndex == (this.nLen-1)) this.tools.setCss(this.tools.getId("gy_photoBox_next"),{"display":"none"});
        },
        imgChange:function(){
            var _that = this,
                _src = this.aBigimg_src[this.nIndex],
                eLoadingTips = this.tools.getId("gy_photoBox_img_loading"),
                eImg = this.tools.getId("gy_photoBox_img"),
                eTitle = this.tools.getId("gy_photoBox_title"),
                eInfor = this.tools.getId("gy_photoBox_infor");
            // 显示loading图片
            this.tools.setCss(eLoadingTips,{"display":"block"});
            this.tools.setCss(eInfor,{"display":"none"});
            // 判断左右按钮显示
            this.btnIsShow();
            // 图片加载处理
            this.imgLoading({
                "src":_src,
                "success":function(){
                    _that.tools.setCss(eLoadingTips,{"display":"none"});
                    _that.tools.setCss(eInfor,{"display":"block"});
                    // 设置真实图片路径,标题,当前页码
                    eImg.src = _src;
                    eTitle.innerHTML = _that.aTitle[_that.nIndex];
                    _that.tools.getId("gy_photoBox_index").innerHTML = (_that.nIndex+1);
                    // 设置样式
                    _that.setBoxCss();
                    // 弹窗呈现
                    _that.tools.setCss(_that.tools.getId("gy_photoBox"),{"visibility":"visible"});
                    if(_that.tools.getId("gy_photoBox_firstLoad")){
                        document.body.removeChild(_that.tools.getId("gy_photoBox_firstLoad"));
                    }
                    // 每次切换执行的回调函数
                    if(typeof _that.opt.onChange == "function"){
                        _that.opt.onChange({"src":_src,"index":_that.nIndex,"title":_that.aTitle[_that.nIndex]});
                    }
                },
                "error":function(){
                    setTimeout(function(){
                        _that.tools.setCss(eLoadingTips,{"display":"none"});
                    },200);
                    eImg.src = "gyPhotoBox/error.png";
                    eTitle.innerHTML = "暂无相关图片";
                    _that.nImgWidth = 400;
                    _that.nImgHeight = 300;
                    _that.setBoxCss();
                    _that.tools.setCss(_that.tools.getId("gy_photoBox"),{"visibility":"visible"});
                    if(_that.tools.getId("gy_photoBox_firstLoad")){
                        document.body.removeChild(_that.tools.getId("gy_photoBox_firstLoad"));
                    }
                }
            });
        },
        btnPrev:function(){
            var _that = this;
            this.tools.getId("gy_photoBox_prev").onclick = function(){
                _that.nIndex--;
                _that.imgChange();
            }
        },
        btnNext:function(){
            var _that = this;
            this.tools.getId("gy_photoBox_next").onclick = function(){
                _that.nIndex++;
                _that.imgChange();
            }
        },
        keyEvent:function(){
            var _that = this;
            document.onkeydown = function(e){
                var e = e || window.event;
                switch(e.keyCode){
                    case 37:{
                        if(_that.nIndex != 0&&_that.tools.getId("gy_photoBox_prev")){
                            _that.nIndex--;
                            _that.imgChange();   
                        }   
                    };break;
                    case 39 :{
                        if(_that.nIndex != (_that.nLen-1)&&_that.tools.getId("gy_photoBox_next")){
                            _that.nIndex++;
                            _that.imgChange();   
                        }           
                    };break;
                    case 27:{
                        _that.removeBox();                           
                    };break;
                }
            }
        },
        /*
        @ src [String] 图片的地址
        @ success [Function] 图片加载成功的回调函数
        @ error [Function] 图片加载失败的回调函数
        */
        imgLoading:function(opt){
            var _img = new Image(),
                _that = this;
            _img.onload = function(){
                _that.nImgWidth = this.width;
                _that.nImgHeight = this.height;
                if(typeof opt.success == "function"){
                    setTimeout(function(){
                        opt.success();
                    },300);
                }
            }
            _img.onerror = function(){
                if(typeof opt.error){
                    opt.error();
                }           
            }
            // 注意:要放在onload事件下面,否则ie会出现BUG
            _img.src = opt.src;
        },
        firstLoad:function(src,callback){
            var _that = this,
                html = document.createElement("div");
                html.id = "gy_photoBox_firstLoad";
            document.body.appendChild(html);
            this.tools.setCss(this.tools.getId("gy_photoBox_firstLoad"),{"top":(document.body.scrollTop || document.documentElement.scrollTop)+(document.documentElement.clientHeight/2) +"px"});
            if(typeof callback == "function") {
                callback();
            }
        },
        windowResize:function(){
            var _that = this,
                _timer = null;
            // 函数节流
            window.onresize = function(){
                clearTimeout(_timer);
                _timer = setTimeout(function(){
                    if( _that.tools.getId("gy_photoBox")){
                        _that.setBoxCss();
                    }
                },100);
            }       
        },
        tools:function(){
            return{
                getEvent:function(e){
                    return e || window.event;
                },
                getTarget:function(e){
                    return e.target || e.srcElement;
                },
                preventDefault:function(e){
                    e.preventDefault?e.preventDefault():e.returnValue = false;
                },
                getId:function(id){
                    return document.getElementById(id);
                },
                getCss:function(node,value){
                    return node.currentStyle?node.currentStyle[value]:getComputedStyle(node,null)[value];
                },
                setCss:function(node,val){
                    for(var v in val){
                        node.style.cssText += ";"+ v +":"+val[v];
                    }
                }
            }
        }()
    }
    window.LGY_photoBox = LGY_photoBox;
})();

最终效果图: