原生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查询数据返回object和字符串影响原因是什么
Aug 09 Javascript
window.navigate 与 window.location.href 的使用区别介绍
Sep 21 Javascript
Javascript中使用A标签获取当前目录的绝对路径方法
Mar 02 Javascript
jquery实现鼠标滑过显示二级下拉菜单效果
Aug 24 Javascript
学习JavaScript设计模式之享元模式
Jan 18 Javascript
JS中JSON对象和String之间的互转及处理技巧
Apr 06 Javascript
简单实现的JQuery文本框水印插件
Jun 14 Javascript
JavaScript计算器网页版实现代码分享
Jul 15 Javascript
JS基于正则实现数字千分位用逗号分隔的方法
Jun 16 Javascript
对于防止按钮重复点击的尝试详解
Apr 22 Javascript
Vue解决移动端弹窗滚动穿透问题
Dec 15 Vue.js
JavaScript canvas实现雨滴特效
Jan 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
js操作ajax返回的json的注意问题!
2010/02/23 Javascript
如何将JS的变量值传递给ASP变量
2012/12/10 Javascript
js获取height和width的方法说明
2013/01/06 Javascript
JavaScript 处理Iframe自适应高度(同或不同域名下)
2013/03/29 Javascript
悬浮数字的实现案例
2014/02/19 Javascript
javascript判断是手机还是电脑访问网页的简单实例分享
2014/06/03 Javascript
JavaScript基础函数整理汇总
2015/01/30 Javascript
bootstrap table 服务器端分页例子分享
2015/02/10 Javascript
JS实现自适应高度表单文本框的方法
2015/02/25 Javascript
使用PHP+JavaScript将HTML页面转换为图片的实例分享
2016/04/18 Javascript
原生JS实现图片轮播与淡入效果的简单实例
2016/08/21 Javascript
js遍历map javaScript遍历map的简单实现
2016/08/26 Javascript
利用JS判断鼠标移入元素的方向
2016/12/11 Javascript
EasyUi 打开对话框后控件赋值及赋值后不显示的问题解决办法
2017/01/19 Javascript
微信小程序 UI与容器组件总结
2017/02/21 Javascript
从对象列表中获取一个对象的方法,依据关键字和值
2017/09/20 Javascript
详解angularjs实现echart图表效果最简洁教程
2017/11/29 Javascript
JavaScript闭包原理与用法实例分析
2018/08/10 Javascript
JS实现鼠标拖拽盒子移动及右键点击盒子消失效果示例
2019/01/29 Javascript
vuex实现数据状态持久化
2019/11/11 Javascript
[00:21]DOTA2亚洲邀请赛 Logo演绎
2015/02/07 DOTA
python中的编码知识整理汇总
2016/01/26 Python
Python使用pip安装pySerial串口通讯模块
2018/04/20 Python
python使用pymongo操作mongo的完整步骤
2019/04/13 Python
Appium+python自动化之连接模拟器并启动淘宝APP(超详解)
2019/06/17 Python
解决Django一个表单对应多个按钮的问题
2019/07/18 Python
Python unittest基本使用方法代码实例
2020/06/29 Python
俄罗斯品牌服装和鞋子的在线商店:KUPIVIP
2019/10/27 全球购物
《雨霖铃》听课反思
2014/02/13 职场文书
英文请假条
2014/04/11 职场文书
中国文明网向国旗敬礼寄语大全
2014/09/27 职场文书
法定授权委托证明书
2015/06/18 职场文书
个人收入证明格式
2015/06/24 职场文书
教育教学读书笔记
2015/07/02 职场文书
《文化苦旅》读后感:阅读,让人诗意地栖居在大地上
2019/12/24 职场文书
vue/cli 配置动态代理无需重启服务的方法
2022/05/20 Vue.js