zoukankan      html  css  js  c++  java
  • 原生javascript-图片弹窗交互效果

    本人的第一个原生js插件 - picLightBox 

    在线例子:http://lgy.1zwq.com/photoBox/

     

    【一】用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;
    })();
  • 相关阅读:
    以太网的寻址
    IP地址简介
    服务器控件与Html控件属性值的解释差异
    The Live Hacking CD
    德国SNS交友/视频网站Poppen.de的技术架构分享
    Forensic Log Parsing with Microsoft's LogParser
    The Flame: Questions and Answers
    hping
    WIN7与XP网络共享与访问
    Win7无法访问NAS或Samba解决之道
  • 原文地址:https://www.cnblogs.com/focuslgy/p/3175547.html
Copyright © 2011-2022 走看看