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中的理解有点不 一样,看示意图:

 JS图片灯箱(lightBox)效果基本原理和demo

JS图片灯箱(lightBox)效果基本原理和demo

以前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下载

你可能感兴趣的:(demo)