原生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高级程序设计阅读笔记(五) ECMAScript中的运算符(一)
Feb 27 Javascript
纯Javascript实现Windows 8 Metro风格实现
Oct 15 Javascript
JS获取url链接字符串 location.href
Dec 23 Javascript
jQuery超赞的评分插件(8款)
Aug 20 Javascript
javascript中字体浮动效果的简单实例演示
Nov 18 Javascript
JavaScript+CSS无限极分类效果完整实现方法
Dec 22 Javascript
AngularJS实现树形结构(ztree)菜单示例代码
Sep 18 Javascript
Ionic3实现图片瀑布流布局
Aug 09 Javascript
angular中ui calendar的一些使用心得(推荐)
Nov 03 Javascript
JavaScript实现的贝塞尔曲线算法简单示例
Jan 30 Javascript
Vue兼容ie9的问题全面解决方案
Jun 19 Javascript
详解vue中v-model和v-bind绑定数据的异同
Aug 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
一个颜色轮换的简单例子
2006/10/09 PHP
php编程实现获取excel文档内容的代码实例
2011/06/28 PHP
优化网页之快速的呈现我们的网页
2007/06/29 Javascript
Javascript isArray 数组类型检测函数
2009/10/08 Javascript
javascript实现简单的贪吃蛇游戏
2015/03/31 Javascript
详解AngularJS中自定义指令的使用
2015/06/17 Javascript
JS数组合并push与concat区别分析
2015/12/17 Javascript
Node.js 实现简单的接口服务器的实例代码
2017/05/23 Javascript
js字符限制(字符截取) 一个中文汉字算两个字符
2017/09/12 Javascript
webpack4 + react 搭建多页面应用示例
2018/08/03 Javascript
vue-cli 打包后提交到线上出现 &quot;Uncaught SyntaxError:Unexpected token&quot; 报错
2018/11/06 Javascript
详解在vue-test-utils中mock全局对象
2018/11/07 Javascript
微信小程序中使用echarts的实现方法
2019/04/24 Javascript
vue element-ui之怎么封装一个自己的组件的详解
2019/05/20 Javascript
vue开发简单上传图片功能
2020/06/30 Javascript
Python 第一步 hello world
2009/09/25 Python
python中xrange用法分析
2015/04/15 Python
Python实现的HMacMD5加密算法示例
2018/04/03 Python
Django实现全文检索的方法(支持中文)
2018/05/14 Python
python使用KNN算法识别手写数字
2019/04/25 Python
Python FFT合成波形的实例
2019/12/04 Python
Pytorch技巧:DataLoader的collate_fn参数使用详解
2020/01/08 Python
python 通过邮件控制实现远程控制电脑操作
2020/03/16 Python
css3 pointer-events 介绍详解
2017/09/18 HTML / CSS
波兰运动鞋网上商店:e-Sporting
2018/02/16 全球购物
.NET里面什么时候需要调用垃圾回收
2015/06/01 面试题
环保建议书200字
2014/05/14 职场文书
英语教师自荐信
2014/05/26 职场文书
质检员岗位职责范本
2015/04/07 职场文书
承诺书模板大全
2015/05/04 职场文书
旅游安全责任协议书
2016/03/22 职场文书
2019年销售人员的职业生涯规划书
2019/03/25 职场文书
Python移位密码、仿射变换解密实例代码
2021/06/27 Python
CSS实现渐变色边框(Gradient borders)的5种方法
2022/03/25 HTML / CSS
第四次工业革命,打工人与机器人的竞争
2022/04/21 数码科技
使用Nginx+Tomcat实现负载均衡的全过程
2022/05/30 Servers