原生javascript实现图片弹窗交互效果


Posted in Javascript onJanuary 12, 2015

【一】用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;

})();

最终效果图:

原生javascript实现图片弹窗交互效果

Javascript 相关文章推荐
jQuery 使用手册(五)
Sep 23 Javascript
iframe异步加载实现点击左边菜单加载右边内容实例讲解
Mar 04 Javascript
JQuery插件开发示例代码
Nov 06 Javascript
Node.js抓取中文网页乱码问题和解决方法
Feb 10 Javascript
Grunt入门教程(自动任务运行器)
Aug 06 Javascript
基于javascript实现彩票随机数生成(升级版)
Apr 17 Javascript
简单解析JavaScript中的__proto__属性
May 10 Javascript
jQuery扩展+xml实现表单验证功能的方法
Dec 25 Javascript
bootstrap选项卡使用方法解析
Jan 11 Javascript
javascript实现圣旨卷轴展开效果(代码分享)
Mar 23 Javascript
JavaScript动态绑定详解
Sep 14 Javascript
vue radio单选框,获取当前项(每一项)的value值操作
Sep 10 Javascript
原生javascript实现图片按钮切换
Jan 12 #Javascript
原生javascript实现图片滚动、延时加载功能
Jan 12 #Javascript
DOM节点的替换或修改函数replaceChild()用法实例
Jan 12 #Javascript
原生javascript实现Tab选项卡切换功能
Jan 12 #Javascript
推荐4个原生javascript常用的函数
Jan 12 #Javascript
原生js实现日期联动
Jan 12 #Javascript
Javascript中innerHTML用法实例分析
Jan 12 #Javascript
You might like
深入PHP异步执行的详解
2013/06/03 PHP
PHP中fwrite与file_put_contents性能测试代码
2013/08/02 PHP
php使用$_POST或$_SESSION[]向js函数传参
2014/09/16 PHP
php+mysqli实现将数据库中一张表信息打印到表格里的方法
2015/01/28 PHP
php版微信公众平台入门教程之开发者认证的方法
2016/09/26 PHP
JavaScript 实现??打印?理
2007/04/28 Javascript
js no-repeat写法 背景不重复
2009/03/18 Javascript
Javascript获取HTML静态页面参数传递值示例
2013/08/18 Javascript
跟我学Node.js(四)---Node.js的模块载入方式与机制
2014/06/04 Javascript
jQuery源码解读之removeAttr()方法分析
2015/02/20 Javascript
js实现超简单的展开、折叠目录代码
2015/08/28 Javascript
简单实现轮播图效果的实例
2016/07/15 Javascript
node.js中的事件处理机制详解
2016/11/26 Javascript
javascript基本数据类型及类型检测常用方法小结
2016/12/14 Javascript
BootStrap selectpicker后台动态绑定数据的方法
2017/07/28 Javascript
关于预加载InstantClick的问题解决方法
2017/09/12 Javascript
vue中v-cloak解决刷新或者加载出现闪烁问题(显示变量)
2018/04/20 Javascript
JS实现京东商品分类侧边栏
2020/12/11 Javascript
js动态添加带圆圈序号列表的实例代码
2021/02/18 Javascript
Python爬虫实例扒取2345天气预报
2018/03/04 Python
Python常见工厂函数用法示例
2018/03/21 Python
Python3 中把txt数据文件读入到矩阵中的方法
2018/04/27 Python
python中报错&quot;json.decoder.JSONDecodeError: Expecting value:&quot;的解决
2019/04/29 Python
Django框架自定义session处理操作示例
2019/05/27 Python
pytorch自定义初始化权重的方法
2019/08/17 Python
Jupyter Notebook 安装配置与使用详解
2021/01/06 Python
详解使用双缓存解决Canvas clearRect引起的闪屏问题
2019/04/29 HTML / CSS
Spartoo葡萄牙鞋类网站:线上销售鞋履与时尚配饰
2017/01/11 全球购物
圣彼得堡鲜花配送:Semicvetic
2020/09/15 全球购物
给小学生的新年寄语
2014/04/04 职场文书
市场营销毕业求职信
2014/08/07 职场文书
董事长秘书岗位职责
2015/02/13 职场文书
宾馆客房管理制度
2015/08/06 职场文书
导游词之苏州阳澄湖
2019/11/15 职场文书
纯html+css实现Element loading效果
2021/08/02 HTML / CSS
mysql主从复制的实现步骤
2021/10/24 MySQL