slider.js 8.38 KB
/*  
    detail页图片滚动插件
    author:liuyue
    date:2015-05-12
*/

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

    ;
    (function(global, undefined) {

        var Slider = function(element, options) {
            this.options = options;
            this.$element = $(element);
            this.$lis = this.$element.children();
            this.len = this.$lis.length;
            this.timer = null;
            this.width = this.$lis.width();
            this.index = 0;
            this.ctrlIndex = 0;
            this.ctrl = this.options.pageCtrl;
            this.ctrlEle = this.options.pageCtrl.children();
            this.ctrlLen = this.ctrlEle.length;
            this.ctrlWidth = this.ctrlEle.width() + parseInt(this.ctrlEle.eq(1).css("marginLeft"));
            this.ctrlMaxLeft = this.ctrl.width() - this.ctrl.parent().width() - parseInt(this.ctrlEle.eq(1).css("marginLeft"));
            this.excessWidth = this.ctrlMaxLeft - this.ctrlWidth * (this.ctrlLen - this.options.ctrlShowNum);
            this.init();
        };


        Slider.DEFAULTS = {
            pageCtrl: '',
            ctrlShowNum: 6,
            prevBtn: $(".detail-slide-ctrl-prev"),
            nextBtn: $(".detail-slide-ctrl-next")
        };


        Slider.prototype = {
            init: function() {
                this.setWidth();
                if (this.options.autoPlay) {
                    this.play();
                }
                this.bindEvent();
                this.addIndex();
                this.options.pageCtrl.children().eq(0).addClass('current');
                if (this.ctrlLen <= this.options.ctrlShowNum) {
                    this.options.prevBtn.hide();
                    this.options.nextBtn.hide();
                }
            },

            setWidth: function() {
                this.$element.width(this.len * this.width);
                this.options.pageCtrl.width(this.ctrlWidth * this.ctrlLen);
                this.ctrlMaxLeft = this.ctrl.width() - this.ctrl.parent().width() - parseInt(this.ctrlEle.eq(1).css("marginLeft"));
                this.excessWidth = this.ctrlMaxLeft - this.ctrlWidth * (this.ctrlLen - this.options.ctrlShowNum);
            },

            addIndex: function() {
                this.options.pageCtrl.children().each(function(i, value) {
                    $(this).attr("index", i);
                })
            },

            bindEvent: function() {
                var _this = this;
                this.options.pageCtrl.children().on("click", function() {
                    if (_this.$element.is(':animated') || $(this).attr('class') == 'current' || _this.options.pageCtrl.is(':animated')) {
                        return;
                    }

                    var myIndex = parseInt($(this).attr("index"));
                    var offset = -_this.width * (myIndex - _this.index);
                    _this.animate(offset);
                    clearTimeout(_this.timer);
                    _this.index = myIndex;
                    if (_this.options.autoPlay) {
                        _this.play();
                    }
                    _this.showButton();

                    _this.slideCtrlSlide($(this).index());

                });
                this.options.prevBtn.on("click.prev", function() {
                    if (_this.options.pageCtrl.is(':animated')) {
                        return;
                    }
                    _this.prev();
                });
                this.options.nextBtn.on("click.next", function() {
                    if (_this.options.pageCtrl.is(':animated')) {
                        return;
                    }
                    _this.next();
                });
            },

            slideCtrlSlide: function(index) {
                var _this = this,
                    left = Math.abs(parseInt($(".detail-slide-ctrl-tabs").css("left")));

                if (index === _this.options.ctrlShowNum - 1 + parseInt(left / _this.ctrlWidth) && left < _this.ctrlMaxLeft) {
                    _this.options.nextBtn.trigger("click.next");
                } else if (index === parseInt(left / _this.ctrlWidth) && left > 0) {
                    _this.options.prevBtn.trigger("click.prev");
                }
            },

            slidePrev: function() {
                var offset;
                if (this.index === 0) return;
                if (this.$element.is(':animated') || this.options.pageCtrl.is(':animated')) return;
                offset = this.width;
                this.index--;
                this.animate(offset);
                this.showButton();
                this.slideCtrlSlide(this.index);
            },

            slideNext: function() {
                var offset;
                if (this.index === this.len - 1) return;
                if (this.$element.is(':animated') || this.options.pageCtrl.is(':animated')) return;
                offset = this.width;
                this.index++;
                this.animate(-offset);
                this.showButton();
                this.slideCtrlSlide(this.index);
            },

            prev: function() {
                var excessWidth = this.excessWidth;
                var maxCtrlIndex = this.ctrlLen - this.options.ctrlShowNum;
                this.ctrlIndex--;

                if (this.ctrlIndex < 0) {
                    this.ctrlIndex = maxCtrlIndex;
                }
                if (this.ctrlIndex == 0) {
                    this.options.pageCtrl.stop().animate({
                        "left": 0
                    });
                } else {
                    this.options.pageCtrl.stop().animate({
                        "left": -this.ctrlWidth * this.ctrlIndex - excessWidth
                    });
                }
            },

            next: function() {
                var maxCtrlIndex = this.ctrlLen - this.options.ctrlShowNum;

                if (this.ctrlIndex < maxCtrlIndex) {
                    this.ctrlIndex++;
                } else {
                    this.ctrlIndex = 0;
                }
                if (this.ctrlIndex == maxCtrlIndex && this.ctrlMaxLeft > 0) {
                    this.options.pageCtrl.stop().animate({
                        "left": -this.ctrlMaxLeft
                    });
                } else {
                    this.options.pageCtrl.stop().animate({
                        "left": -this.ctrlWidth * this.ctrlIndex
                    });
                }
            },

            showButton: function() {
                this.options.pageCtrl.children().eq(this.index).addClass('current').siblings().removeClass('current');
            },

            animate: function(offset) {
                var left = parseInt(this.$element.css('left')) + offset;
                var _this = this;
                if (offset > 0) {
                    offset = '+=' + offset;
                } else {
                    offset = '-=' + Math.abs(offset);
                }
                this.$element.stop().animate({
                    'left': offset
                }, 300);
            },

            //屏幕改变大小时重新计算
            resize: function() {
                this.width = this.$lis.width();
                this.ctrlWidth = this.ctrlEle.width() + parseInt(this.ctrlEle.eq(1).css("marginLeft"));
                this.setWidth();
                this.$element.css({
                    'left': -this.index * this.width
                });
                if (this.ctrlIndex == 0) return;
                this.options.pageCtrl.css({
                    "left": -this.ctrlWidth * this.ctrlIndex - this.excessWidth
                });

            }
        }


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

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


        $.fn.slider = Plugin;
        $.fn.slider.Constructor = Slider;

    })(this);
});