原生javascript实现图片弹窗交互效果

  【一】用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实现图片弹窗交互效果