JS圖片燈箱(lightBox)效果基本原理和demo


       到年底了,項目不怎么忙,所以有空特地研究了下KISSY中源碼JS燈箱效果,感覺代碼比較簡單,所以就按照他們的思路依賴於Jquery框架也封裝了一個,特地分享給大家,以前經常看到網上很多這樣的插件,感覺很多人很牛逼的樣子,這樣的效果也能做出來,碰巧今天自己也能研究出來一個,代碼也不多,就300多行代碼,嘿嘿!如果寫的不夠好,或者還不夠的,希望大家多多指教!或者多多發表意見,那些需要值得改進的地方!共同學習!

基本原理

    點擊縮略圖浮層顯示大圖,可點擊鍵盤←、→鍵切換圖片,也可以鼠標點擊左右箭頭切換。按下鍵盤Esc鍵和點擊關閉按鈕效果一致。

配置項如下:

  container
'#container',   container 容器標識,父級盒子ID
targetCls  '.J_lightbox',     targetCls 元素選擇器,需要彈出的圖片鏈接dom節點
layer  '#lightbox',    浮層模版選擇器
 closebtn   '.closebtn',        關閉浮層的X按鈕
prev '.prevbtn',         上一張觸發器
next '.nextbtn',          下一張觸發器
easing 'linear'            jquery 動畫函數 默認為 'linear' 或者 'swing' 或者jquery自帶的動畫效果

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({});
 });
View Code

總結:

   春節前是最后一篇博客,嘿嘿!28號凌晨2點的火車,今天晚上動身回家了!呵呵!羡慕嫉妒恨吧!哈哈.....

demo下載


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM