本人的第一个原生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; })();