原生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 错误处理与调试经验总结
Aug 10 Javascript
玩转jQuery按钮 请告诉我你最喜欢哪些?
Jan 08 Javascript
jquery 触发a链接点击事件解决方案
May 02 Javascript
jQuery中after的两种用法实例
Jul 03 Javascript
jQuery入门介绍之基础知识
Jan 13 Javascript
jQuery点击按钮弹出遮罩层且内容居中特效
Dec 14 Javascript
基于jquery实现智能表单验证操作
May 09 Javascript
jQuery Ajax 全局调用封装实例代码详解
Jun 02 Javascript
浅谈Angular HttpClient简单入门
May 04 Javascript
微信小程序实现签到功能
Oct 31 Javascript
vue+element tabs选项卡分页效果
Jun 29 Javascript
vue获取data数据改变前后的值方法
Nov 07 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+MySQL插入操作实例
2015/01/21 PHP
php禁用cookie后session设置方法分析
2016/10/19 PHP
php封装的pdo数据库操作工具类与用法示例
2019/05/08 PHP
Js 刷新框架页的代码
2010/04/13 Javascript
js使用onmousemove和onmouseout获取鼠标坐标的方法
2015/03/31 Javascript
js+html5通过canvas指定开始和结束点绘制线条的方法
2015/06/05 Javascript
JavaScript识别网页关键字并进行描红的方法
2015/11/09 Javascript
javascript基于prototype实现类似OOP继承的方法
2015/12/16 Javascript
实例讲解jQuery中对事件的命名空间的运用
2016/05/24 Javascript
Easyui笔记2:实现datagrid多行删除的示例代码
2017/01/14 Javascript
JavaScript在控件上添加倒计时功能的实现代码
2017/07/04 Javascript
Vue框架中正确引入JS库的方法介绍
2017/07/30 Javascript
原生JS获取元素的位置与尺寸实现方法
2017/10/18 Javascript
Vue.js做select下拉列表的实例(ul-li标签仿select标签)
2018/03/02 Javascript
vue-cli与webpack处理静态资源的方法及webpack打包的坑
2018/05/15 Javascript
.vue文件 加scoped 样式不起作用的解决方法
2018/05/28 Javascript
JS高阶函数原理与用法实例分析
2019/01/15 Javascript
你不知道的Vue技巧之--开发一个可以通过方法调用的组件(推荐)
2019/04/15 Javascript
vue实现手机号码的校验实例代码(防抖函数的应用场景)
2019/09/05 Javascript
微信小程序在text文本实现多种字体样式
2019/11/08 Javascript
python批量导出导入MySQL用户的方法
2013/11/15 Python
Python验证码识别处理实例
2015/12/28 Python
详解用TensorFlow实现逻辑回归算法
2018/05/02 Python
Python获取航线信息并且制作成图的讲解
2019/01/03 Python
15行Python代码实现网易云热门歌单实例教程
2019/03/10 Python
VSCode基础使用与VSCode调试python程序入门的图文教程
2020/03/30 Python
Diamondback自行车:拥有你的冒险
2019/04/22 全球购物
高中自我鉴定
2013/12/20 职场文书
小学运动会表扬稿
2014/01/19 职场文书
广告学专业求职信
2014/06/19 职场文书
校园元旦活动总结
2014/07/09 职场文书
人身损害赔偿协议书范本
2014/09/27 职场文书
起诉离婚协议书样本
2014/11/25 职场文书
停电调休通知
2015/04/16 职场文书
会议主持词开场白
2015/05/28 职场文书
Java中PriorityQueue实现最小堆和最大堆的用法
2021/06/27 Java/Android