到年底了,專案不怎麼忙,所以有空特地研究了下KISSY中原始碼JS燈箱效果,感覺程式碼比較簡單,所以就按照他們的思路依賴於Jquery框架也封裝了一個,特地分享給大家,以前經常看到網上很多這樣的外掛,感覺很多人很牛逼的樣子,這樣的效果也能做出來,碰巧今天自己也能研究出來一個,程式碼也不多,就300多行程式碼,嘿嘿!如果寫的不夠好,或者還不夠的,希望大家多多指教!或者多多發表意見,那些需要值得改進的地方!共同學習!
基本原理
點選縮圖浮層顯示大圖,可點選鍵盤←、→鍵切換圖片,也可以滑鼠點選左右箭頭切換。按下鍵盤Esc鍵和點選關閉按鈕效果一致。
配置項如下:
JSFiddle效果如下
程式碼中需要了解的知識點如下:
1. getBoundingClientRect()方法:該方法獲得頁面中某個元素的左,上,右和下分別相對瀏覽器視窗的位置,他返回的是一個物件,即Object,該物件有是個屬 性:top,left,right,bottom;這裡的top、left和css中的理解很相似,但是right,bottom和css中的理解有點不 一樣,看示意圖:
以前getBoundingClientRect()是IE特有的,目前FF3+,opera9.5+,safari 4,都已經支援這個方法。所以相容性都支援的。
2. 判斷圖片是否載入完成時 標準瀏覽器用onload觸發,IE用私有屬性onreadystatechange觸發,需要了解更深入的話 可以閱讀這篇文章:想看我,先點選我!ok!
程式碼簡單的分析下:
1.頁面初始化時候 呼叫init方法,執行點選_click()函式。如下程式碼:
init: function(options) { this.config = $.extend(this.config, options || {}); var self = this, _config = self.config; // 點選 self._click(); },
2. 點選_click()函式做了如下事情:
1. 點選縮圖:呼叫 self._showLoadMask(); // 顯示loading載入效果 就是頁面未載入或者網速慢的時候 顯示載入轉圈那種效果。
2. self._onLoad($(this).attr('href'),this); // 執行此方法載入大圖片。
3. 滑鼠mouerover事件和mouseout事件觸發 如下程式碼:
// 滑鼠mouseover事件(移到動畫層) $(_config.layer).mouseover(function(){ if(_cache.currentImg != 0) { $(_config.prev).css('display','block'); } if(_cache.currentImg != ($(_config.targetCls).length - 1)) { $(_config.next).css('display','block'); } });
// 滑鼠移出 隱藏上一頁按鈕 下一頁按鈕 $(_config.layer).mouseout(function(){ $(_config.prev).css('display','none'); $(_config.next).css('display','none'); });
4. 點選上一頁按鈕 或 下一頁按鈕 圖片切換做相應的操作:如下程式碼:
// 點選上一頁按鈕 $(_config.prev).unbind('click').bind('click',function(){ _cache.currentImg -= 1; self._onLoad($($(_config.targetCls)[_cache.currentImg]).attr('href'),$(_config.targetCls)[_cache.currentImg]); if(_cache.currentImg == 0) { $(_config.prev).css('display','none'); }else { $(_config.prev).css('display','block'); } $(_config.next).css('display','block'); });
// 點選下一頁按鈕 $(_config.next).unbind('click').bind('click',function(){ _cache.currentImg += 1; self._onLoad($($(_config.targetCls)[_cache.currentImg]).attr('href'),$(_config.targetCls)[_cache.currentImg]); if(_cache.currentImg == ($(_config.targetCls).length - 1)) { $(_config.next).css('display','none'); }else { $(_config.next).css('display','block'); } $(_config.prev).css('display','block'); });
5. 點選關閉按鈕觸發關閉事件,程式碼如下:
$(_config.closebtn).unbind('click').bind('click',function(){ var position = self._getPos($(_config.targetCls)[_cache.currentImg]), width = $($(_config.targetCls)[_cache.currentImg]).width(), height = $($(_config.targetCls)[_cache.currentImg]).height(); $('img',_config.layer).attr('src','http://m2.img.papaapp.com/farm5/d/2014/0126/14/E6520E9D47F0FE8AB04B93BE922C6707_ORIG_1_1.gif'); $(_config.layer).animate({ 'left' : position.x, 'top' : position.y, 'width' : width, 'height' : height, "borderWidth": 0 },0.2,_config.easing,function(){ $(_config.layer).css('display','none'); _cache.isShow = false; }); });
6.鍵盤左右鍵除法事件程式碼如下:
/* * 鍵盤左右鍵觸發 Esc鍵碼27 鍵盤右移鍵39 左移鍵 37 */ $(document).unbind('keydown').bind('keydown',function(e){ var keyCode = e.keyCode; if(_cache.isShow) { if(keyCode == 27) { $(_config.closebtn).click(); }else if(keyCode == 37) { if(_cache.currentImg == 0) { return; } $("#maskLayer").css('display','block'); $(_config.prev).click(); }else if(keyCode == 39) { if(_cache.currentImg == ($(_config.targetCls).length - 1)) { return; } $("#maskLayer").css('display','block'); $(_config.next).click(); } } });
7. 視窗縮放事件 程式碼如下:
// 視窗縮放事件 $(window).resize(function(){ if(_cache.isShow){ if(self.isrun && $(self.isrun).is(":animated")) { $(self.isrun).stop(); } self._onLoad($($(_config.targetCls)[_cache.currentImg]).attr('href'),$(_config.targetCls)[_cache.currentImg]); } });
3. 下面還有幾個方法不一一解析了 有興趣的童鞋可以看看程式碼,下面會提供demo下載或在看看上面Jsfiddle連結效果或者原始碼:分別是:
_showLoadMask().顯示loading載入效果
_onLoad() 載入大圖片
_getCenter() 層居中對齊
下面是所有的JS程式碼如下:
/** * JS燈箱效果 * @time 2014-1-24 * @author tugenhua */ function LightBox(options) { /** * 引數說明 * @container 容器標識,父級盒子ID * @targetCls 元素選擇器,需要彈出的圖片連結dom節點 * @layer 浮層模版選擇器 * @closebtn 關閉浮層的X按鈕 * @prev 上一張觸發器 * @next 下一張觸發器 * @easing jquery 動畫函式 預設為 'linear' 或者 'swing' 或者jquery自帶的動畫效果 */ this.config = { container : '#container', targetCls : '.J_lightbox', layer : '#lightbox', closebtn : '.closebtn', prev : '.prevbtn', next : '.nextbtn', easing : 'linear' }; this.cache = { isShow : false, currentImg : null }; // 初始化 this.init(options); } LightBox.prototype = { constructor: LightBox, init: function(options) { this.config = $.extend(this.config, options || {}); var self = this, _config = self.config; // 點選 self._click(); }, /* * 獲取元素的位置 * @method _getPos() * @param node 元素的節點 * {private} */ _getPos: function(node) { var pos = {}, xy = $(node)[0].getBoundingClientRect(), sl = $(window).scrollLeft(), st = $(window).scrollTop(); pos.x = xy.left + sl; pos.y = xy.top + st; return pos; }, /* * 點選頁面上圖片 * @method _click(); * {private} */ _click: function() { var self = this, _config = self.config, _cache = self.cache; $(_config.targetCls,_config.container).each(function(index,item) { $(item).unbind('click'); $(item).bind('click',function(e){ e.preventDefault(); _cache.currentImg = $(_config.targetCls).index($(this)); // 顯示loading載入效果 self._showLoadMask(); // 載入內容 self._onLoad($(this).attr('href'),this); }); // 滑鼠mouseover事件(移到動畫層) $(_config.layer).mouseover(function(){ if(_cache.currentImg != 0) { $(_config.prev).css('display','block'); } if(_cache.currentImg != ($(_config.targetCls).length - 1)) { $(_config.next).css('display','block'); } }); // 滑鼠移出 隱藏上一頁按鈕 下一頁按鈕 $(_config.layer).mouseout(function(){ $(_config.prev).css('display','none'); $(_config.next).css('display','none'); }); // 點選上一頁按鈕 $(_config.prev).unbind('click').bind('click',function(){ _cache.currentImg -= 1; self._onLoad($($(_config.targetCls)[_cache.currentImg]).attr('href'),$(_config.targetCls)[_cache.currentImg]); if(_cache.currentImg == 0) { $(_config.prev).css('display','none'); }else { $(_config.prev).css('display','block'); } $(_config.next).css('display','block'); }); // 點選下一頁按鈕 $(_config.next).unbind('click').bind('click',function(){ _cache.currentImg += 1; self._onLoad($($(_config.targetCls)[_cache.currentImg]).attr('href'),$(_config.targetCls)[_cache.currentImg]); if(_cache.currentImg == ($(_config.targetCls).length - 1)) { $(_config.next).css('display','none'); }else { $(_config.next).css('display','block'); } $(_config.prev).css('display','block'); }); // 點選關閉按鈕X 隱藏lightBox圖片 $(_config.closebtn).unbind('click').bind('click',function(){ var position = self._getPos($(_config.targetCls)[_cache.currentImg]), width = $($(_config.targetCls)[_cache.currentImg]).width(), height = $($(_config.targetCls)[_cache.currentImg]).height(); $('img',_config.layer).attr('src','http://m2.img.papaapp.com/farm5/d/2014/0126/14/E6520E9D47F0FE8AB04B93BE922C6707_ORIG_1_1.gif'); $(_config.layer).animate({ 'left' : position.x, 'top' : position.y, 'width' : width, 'height' : height, "borderWidth": 0 },0.2,_config.easing,function(){ $(_config.layer).css('display','none'); _cache.isShow = false; }); }); /* * 鍵盤左右鍵觸發 Esc鍵碼27 鍵盤右移鍵39 左移鍵 37 */ $(document).unbind('keydown').bind('keydown',function(e){ var keyCode = e.keyCode; if(_cache.isShow) { if(keyCode == 27) { $(_config.closebtn).click(); }else if(keyCode == 37) { if(_cache.currentImg == 0) { return; } $("#maskLayer").css('display','block'); $(_config.prev).click(); }else if(keyCode == 39) { if(_cache.currentImg == ($(_config.targetCls).length - 1)) { return; } $("#maskLayer").css('display','block'); $(_config.next).click(); } } }); // 視窗縮放事件 $(window).resize(function(){ if(_cache.isShow){ if(self.isrun && $(self.isrun).is(":animated")) { $(self.isrun).stop(); } self._onLoad($($(_config.targetCls)[_cache.currentImg]).attr('href'),$(_config.targetCls)[_cache.currentImg]); } }); }); }, /* * 顯示loading載入效果 * @method _showLoadMask() * {private} */ _showLoadMask: function(){ var self = this, _config = self.config, _cache = self.cache; var maskLayer = $('#maskLayer'), left, top; // 有的話 不需要建立 否則的話 建立load圖示層 if(maskLayer.length > 0) { left = ($(window).width() - $(maskLayer).width()) / 2 + $(window).scrollLeft(), top = ($(window).height() - $(maskLayer).height()) / 2 + $(window).scrollTop(); $(maskLayer).css({'left':left + 'px','top':top + 'px','display':'block'}); }else { var mask = $("<div id='maskLayer' class='maskLayer'></div>"); // 載入loading圖示 $(mask).html("<img src='http://img02.taobaocdn.com/tps/i2/T115PmXipeXXaY1rfd-32-32.gif'>"); $('body').append(mask); maskLayer = $('#maskLayer'); left = ($(window).width() - $(maskLayer).width()) / 2 + $(window).scrollLeft(), top = ($(window).height() - $(maskLayer).height()) / 2 + $(window).scrollTop(); $(maskLayer).css({'left':left + 'px','top':top + 'px','display':'block'}); } }, /* * 載入大圖片 * @method _onLoad() * @param {href,this} 當前的大圖片的src 當前點選圖片元素節點 */ _onLoad: function(src,$this){ var self = this, _config = self.config, _cache = self.cache; // 建立img var img = new Image(), isIE = navigator.userAgent.match(/MSIE/)!= null; if(!isIE) { img.onload = function() { if(img.complete == true) { // 圖片定位居中 self._getCenter(img,$this); } } }else { /* * ie6,7,8 * readyState:complete 動態建立的 IMG 標記可以觸發 onreadystatechange 事件 */ img.onreadystatechange = function() { if(img.readyState == 'loaded' || img.readyState == 'complete') { // 圖片定位居中 self._getCenter(img,$this); } } } img.src = src; }, /* * 層居中對齊 * @method _getCenter(); * @param {img,$this} 動態建立img 當前點選圖片元素節點 */ _getCenter: function(img,$this) { var self = this, _config = self.config, _cache = self.cache; // 先隱藏load圖示 $("#maskLayer") && $("#maskLayer").css('display','none'); var img_w = img.width, img_h = img.height, win_w = $(window).width(), win_h = $(window).height(), left = $(window).scrollLeft(), top = $(window).scrollTop(); img_w = (img_w > win_w - 20) ? win_w - 20 : img_w; var layer_left = (win_w - img_w)/2 + left, layer_top = (win_h - img_h)/2 + top; var position = self._getPos($this), layer_width = $($this).width(), layer_height = $($this).height(); var layer_img = $('img',_config.layer); $(layer_img).attr('src','http://m2.img.papaapp.com/farm5/d/2014/0126/14/E6520E9D47F0FE8AB04B93BE922C6707_ORIG_1_1.gif'); $(layer_img).css({'width':img_w,'height':img_h}); $(layer_img).fadeOut(0.3); layer_left = layer_left < 0 ? 0 : layer_left; layer_top = layer_top < 0 ? 0 : layer_top; if(!_cache.isShow) { $(_config.layer).css({ 'width' : layer_width, 'height' : layer_height, 'left' : position.x, 'top' : position.y, 'display' : 'block' }); _cache.isShow = true; if(self.isrun && $(self.isrun).is(":animated")) { $(self.isrun).stop(); } self.isrun = $(_config.layer).animate({ 'left' : layer_left, 'top' : layer_top, 'width' : img_w, 'height' : img_h, "borderWidth": "10px" }, 0.3,_config.easing,function(){ $(layer_img).attr('src',$(img).attr('src')); $(layer_img).fadeIn(0.3); }); }else { if(self.isrun && $(self.isrun).is(":animated")) { $(self.isrun).stop(); } self.isrun = $(_config.layer).animate({ 'left' : layer_left, 'top' : layer_top, 'width' : img_w, 'height' : img_h }, 0.3,_config.easing,function(){ $(layer_img).attr('src',$(img).attr('src')); $(layer_img).fadeIn(0.3); }); } } }; // 初始化 $(function(){ new LightBox({}); });
總結:
春節前是最後一篇部落格,嘿嘿!28號凌晨2點的火車,今天晚上動身回家了!呵呵!羨慕嫉妒恨吧!哈哈.....