• 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下载

  • 相关阅读:
    电商项目中商品规格数据库的设计
    Spring开发一个简单的starter——c3p0自动配置
    Spring boot 自动配置原理
    Spring MVC中配置静态资源处理的三种方式和区别
    通配符的匹配很全面, 但无法找到元素 'tx:annotation-driven' 的声明
    基于注解和配置类的SSM(Spring+SpringMVC+Mybatis)项目详细配置
    基于注解和xml配置的SSM(Spring+SpringMVC+Mybatis)项目详细配置
    css position 属性 (absolute 和fixed 区别)
    asp.net 网站所有请求跳转到同一个页面
    Javascript 闭包
  • 原文地址:https://www.cnblogs.com/tugenhua0707/p/3534675.html
Copyright © 2020-2023  润新知