原生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 相关文章推荐
javascript 嵌套的函数(作用域链)
Mar 15 Javascript
jquery $.ajax各个事件执行顺序
Oct 15 Javascript
jQuery.query.js 取参数的两点问题分析
Aug 06 Javascript
JavaScript高级程序设计 阅读笔记(二十) js错误处理
Aug 14 Javascript
Javascript写入txt和读取txt文件示例
Feb 12 Javascript
Node.js操作mysql数据库增删改查
Mar 30 Javascript
js轮播图无缝滚动效果
Jun 17 Javascript
node.js基于express使用websocket的方法
Nov 09 Javascript
JavaScript的Object.defineProperty详解
Jul 09 Javascript
layui框架table 数据表格的方法级渲染详解
Aug 19 Javascript
解决VUE双向绑定失效的问题
Oct 29 Javascript
vue使用swiper实现左右滑动切换图片
Oct 16 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插件 HTMLPurifier HTML解析器
2013/07/01 PHP
隐藏Nginx或Apache以及PHP的版本号的方法
2016/01/03 PHP
Zend Framework实现多文件上传功能实例
2016/03/21 PHP
PHP数学运算与数据处理实例分析
2016/04/01 PHP
PHP Laravel中的Trait使用方法
2019/01/20 PHP
PHP autoload使用方法及步骤详解
2020/09/05 PHP
javascript 事件绑定问题
2011/01/01 Javascript
基于jQuery实现的Ajax 验证用户名是否存在的实现代码
2011/04/06 Javascript
修改file按钮的默认样式实现代码
2013/04/23 Javascript
JavaScript实现的一个日期格式化函数分享
2014/12/06 Javascript
JavaScript中的对象与JSON
2015/07/03 Javascript
javascript性能优化之事件委托实例详解
2015/12/12 Javascript
js实现无缝循环滚动
2020/06/23 Javascript
JavaScript将base64图片转换成formData并通过AJAX提交的实现方法
2016/10/24 Javascript
easyui导出excel无法弹出下载框的快速解决方法
2016/11/10 Javascript
ThinkJS中如何使用MongoDB的CURD操作
2016/12/13 Javascript
微信小程序之网络请求简单封装实例详解
2017/06/28 Javascript
vue中echarts图表大小适应窗口大小且不需要刷新案例
2020/07/19 Javascript
Python3实现简单可学习的手写体识别(实例讲解)
2017/10/21 Python
python清理子进程机制剖析
2017/11/23 Python
django echarts饼图数据动态加载的实例
2019/08/12 Python
python实现图片二值化及灰度处理方式
2019/12/07 Python
Python自动化xpath实现自动抢票抢货
2020/09/19 Python
python利用appium实现手机APP自动化的示例
2021/01/26 Python
html5 postMessage前端跨域并前端监听的方法示例
2018/11/01 HTML / CSS
StubHub哥伦比亚:购买和出售您的门票
2016/10/20 全球购物
选购世界上最好的美妆品:Cult Beauty
2017/11/03 全球购物
澳大利亚现代波西米亚风格女装网站:Bohemian Traders
2018/04/16 全球购物
全球独特生活方式产品和礼品购物网站:AHAlife
2018/09/18 全球购物
一份全面的PHP面试问题考卷
2012/07/15 面试题
信息系统专业个人求职信范文
2013/12/07 职场文书
商务专员岗位职责范本
2014/06/29 职场文书
公安派出所所长四风问题个人对照检查材料
2014/10/04 职场文书
英语导游词
2015/02/13 职场文书
2019年公司快递收发管理制度模板
2019/11/20 职场文书
如何让vue长列表快速加载
2021/03/29 Vue.js