imgZoom.js 9.01 KB
/*  
 * 图片放大轮播插件
 * author:liuyue
 * date:2015-04-23
 */

define('plugins/imgZoom', function(require, exports) {
    var $ = require("jquery");


    ;
    (function(global, undefined) {

        var ImgZoom = function(element, options) {
            this.$element = $(element);
            this.options = options;
            this.$tpl = ''; //大图存放模板
            this.$overlay = ''; //黑色透明背景
            this.$zoomBox = ''; //大图最外层包裹
            this.imgHeight = 0; //大图高度
            this.imgWidth = 0; //大图宽度
            this.$btnPrev = ''; //前一张按钮
            this.$btnNext = ''; //后一张按钮
            this.currentClass = 'currentPhoto'; //当前图片的标识类

            this.init();
        };


        ImgZoom.DEFAULTS = {
            originalAttr: 'data-original', //图片原图存放属性
            styleClass: '',
            imgTag: '',
            isContainer: false //杂志页需求
        };


        ImgZoom.prototype = {

            init: function() {
                this._create();

                this._bindEvent();

                if (this.options.isContainer) {
                    this.$element.find('[' + this.options.originalAttr + ']').eq(0).trigger('click.imgzoom');
                }

            },

            /*  
             * 创建大图模板
             */
            _create: function() {
                var that = this;
                if ($('.img-zoom').size() <= 0) {
                    this.$tpl = $('<div class="img-zoom ' + this.options.styleClass + '" onselectstart="return false" unselecttable="on">' +
                        '<img src="" />' +
                        '<a href="javascript:;" class="close-btn"></a>' +
                        '<a href="javascript:;" class="guide-btn prev"></a>' +
                        '<a href="javascript:;" class="guide-btn next"></a>' +
                        '</div>' +
                        '<div class="overlay"></div>');
                    $('body').append(this.$tpl);
                }
                this.$overlay = $('.overlay');
                this.$zoomBox = $('.img-zoom');
                this.$btnPrev = $('.guide-btn.prev');
                this.$btnNext = $('.guide-btn.next');
            },

            /*  
             * 事件绑定
             */
            _bindEvent: function() {
                var that = this;
                //图片点击事件
                this.$element.on('click.imgzoom', '[' + this.options.originalAttr + ']', function() {
                    that.$element.find("." + that.currentClass).removeClass(that.currentClass);
                    $(this).addClass(that.currentClass);
                    $('.img-zoom').data('target', that);
                    that._photoEfficiency();

                    //yohood标签显示需求
                    if (that.options.imgTag !== '') {
                        that.$zoomBox.find('.' + that.options.imgTag).remove();
                        that.$element.find('.' + that.options.imgTag).clone().appendTo(that.$zoomBox);
                    }
                });

                //点击zoom外部隐藏zoom及overlay
                this.$overlay.on('click', function() {
                    that._zoomHide();
                });

                this.$btnPrev.off('click');
                this.$btnNext.off('click');

                this.$btnPrev.on('click', function() {
                    _this = $('.img-zoom').data('target');
                    _this._photoSwitch(_this.$element.find('[' + _this.options.originalAttr + ']').index(_this.$element.find("." + _this.currentClass)), "left");
                });

                this.$btnNext.on("click", function() {
                    _this = $('.img-zoom').data('target');
                    _this._photoSwitch(_this.$element.find('[' + _this.options.originalAttr + ']').index(_this.$element.find("." + _this.currentClass)), "right");
                });
                this.$zoomBox.on('click', '.close-btn', function() {
                    that._zoomHide();
                })
            },

            /*  
             * 图片显示效果
             */
            _photoEfficiency: function() {
                var that = this,
                    hiddenImg = $('<img id="bigpic" src="' + this.$element.find("." + this.currentClass).attr(this.options.originalAttr) + '">').appendTo("body").css({
                        "position": "fixed",
                        'left': '-9999px',
                        'top': '-9999px'
                    });;

                this._loadImg(hiddenImg.attr('src'), function() {
                    that.$zoomBox.find('img').remove().end().prepend(hiddenImg.removeAttr("style"));

                    //图片显示
                    that._zoomShow();

                    if (that.$zoomBox.find('img').outerHeight() > $(window).height()) {
                        that.$zoomBox.find('img').height($(window).height() - 20);
                    }
                    if (that.$zoomBox.find('img').outerWidth() > $(window).width()) {
                        that.$zoomBox.find('img').width($(window).width());
                    }

                    that.imgHeight = that.$zoomBox.find('img').outerHeight();
                    that.imgWidth = that.$zoomBox.find('img').outerWidth();

                    that.$zoomBox.css({
                        "marginTop": -that.imgHeight / 2,
                        "marginLeft": -that.imgWidth / 2
                    })

                });


                //检测首尾状态
                this._getArrowState();
            },

            /*  
             * zoom及overlay显示
             */
            _zoomShow: function() {
                this.$overlay.addClass("show");
                this.$zoomBox.addClass("show");
            },

            /*  
             * zoom及overlay隐藏
             */
            _zoomHide: function() {
                this.$overlay.removeClass("show");
                this.$zoomBox.removeClass("show");
            },

            /*  
             * 检测首尾状态
             */
            _getArrowState: function() {
                if (this.$element.find('[' + this.options.originalAttr + ']').index(this.$element.find("." + this.currentClass)) == 0) {
                    this.$btnPrev.hide();
                } else {
                    this.$btnPrev.show();
                }
                if (this.$element.find('[' + this.options.originalAttr + ']').index(this.$element.find("." + this.currentClass)) == this.$element.find('[' + this.options.originalAttr + ']').size() - 1) {
                    this.$btnNext.hide();
                } else {
                    this.$btnNext.show();
                }
            },

            /*  
             * 图片左右切换
             * @param: index为当前图片索引,direction为切换方向
             */
            _photoSwitch: function(index, direction) {
                var _index;

                this.$element.find('.' + this.currentClass).removeClass(this.currentClass);
                if (direction === 'left') {
                    _index = index - 1;
                } else {
                    _index = index + 1;
                }
                this.$element.find('[' + this.options.originalAttr + ']:eq(' + _index + ')').addClass(this.currentClass);
                this._photoEfficiency();
            },

            /*  
             * 图片load
             * @param: src为要load的图片src
             */
            _loadImg: function(src, callback) {
                var img = new Image();
                if ($.browser.msie) {
                    img.onreadystatechange = function() {
                        if (this.readyState == "complete") {
                            callback.call(img); //将回调函数的this替换为Image对象
                            img = null;
                        }
                    }

                } else {
                    img.onload = function() { //图片下载完毕时异步调用callback函数。
                        callback.call(img); //将回调函数的this替换为Image对象
                        img = null;
                    };
                }
                img.src = src;
            }
        }


        function Plugin(option, _relatedTarget) {
            return this.each(function() {
                var $this = $(this);
                var data = $this.data('yoho.imgZoom');
                var options = $.extend({}, ImgZoom.DEFAULTS, $this.data(), typeof option == 'object' && option);
                // 如果没有初始化,则初始化该对象,并且把该对象绑定到此元素的yoho.PicSilder属性下。
                if (!data) $this.data('yoho.imgZoom', (data = new ImgZoom(this, options)));

                // 如果传递的options是一个字符串,则表示调用改对象的原型方法。
                if (typeof option == 'string') data[option](_relatedTarget);
            });
        };


        $.fn.imgZoom = Plugin;
        $.fn.imgZoom.Constructor = ImgZoom;

    })(this);
});