/** * date: 2015-12-01 author: hishion example: //--------- js $('.hislider').hislider(); //--------- html
*/ ;(function($){ function slider($container, options){ this.$container = $container; this.options = $.extend({ //开始索引 0开始 startslide: 0, //子元素选择器 item: '.hislider-item', //是否全屏 isfullscreen: false, //是否自适应 isflexible: false, //是否支持触摸 html5 transform: issupporttouch: '__proto__' in {}, //是否显示分页按钮 isshowpage: false, //是否显示标题栏 isshowtitle: true, //标题文本存放的属性 或者回调函数(需要返回值) titleattr: 'data-title', //是否显示左右控制按钮 isshowcontrols: true, //是否自动播放 isauto: true, //自动播放间隔时间 intervaltime: 5000, //特效时间 affecttime: 300, //特效类型 string : fade || move mode: 'move', //方向 string: left || top direction: 'left', //开始滑动回调 onswipestart: $.noop, //滑动中回调 onswipemove: $.noop, //正常滑动的最小值 minswipelength: 30, //滑动取消回调 和 minswipelength值有关 onswipecancel: $.noop, //触摸结束回调 (正常触摸) onswipeend: $.noop, //向左滑动回调 onswipeleft: $.noop, //向右滑动回调 onswiperight: $.noop, //向上滑动回调 onswipetop: $.noop, //向下滑动回调 onswipebottom: $.noop, //初始化后回调 oninited: $.noop, //运动前回调 onmovebefore: $.noop, //运动后回调 onmoveafter: $.noop, //分页选中回调 onselected: $.noop }, options); this.init(); } slider.prototype = { init: function(){ this.$item = this.$container.find(this.options.item); this.size = this.$item.size(); this.curindex = this.options.startslide; this.setlayout(); this.playtimer = null; this.options.isauto && this.autoplay(); this.options.isflexible && $(window).on('resize.hislider', $.proxy(this, 'resize')); this.options.issupporttouch && this.touch(); }, touch: function(){ var self = this; var touch = {}; var opt = this.options; var min = opt.minswipelength; this.$container.on('touchstart', function(e){ var touches = e.originalevent.touches[0]; touch.x1 = touches.pagex; touch.y1 = touches.pagey; opt.onswipestart.call(this, touch); }).on('touchmove', function(e){ var touches = e.originalevent.touches[0]; touch.x2 = touches.pagex; touch.y2 = touches.pagey; opt.onswipemove.call(this, touch); }).on('touchend', function(e){ if((touch.x2 && math.abs(touch.x1 - touch.x2) > min) || (touch.y2 && math.abs(touch.y1 - touch.y2) > min)){ var dir = self.swipedirection(touch.x1, touch.x2, touch.y1, touch.y2); opt['onswipe'+dir].call(this, touch); self.moveto(dir); opt.onswipeend.call(this, touch); }else{ opt.onswipecancel.call(this, touch); } touch = {}; }); }, moveto: function(dir){ var self = this; var direction = self.options.direction; if(direction == 'top'){ if(dir == 'bottom'){ self[self.options.mode+'prev'](); }else if(dir == 'top'){ self[self.options.mode](); } }else if(direction == 'left'){ if(dir == 'right'){ self[self.options.mode+'prev'](); }else if(dir == 'left'){ self[self.options.mode](); } } }, swipedirection: function (x1, x2, y1, y2){ var xdelta = math.abs(x1 - x2), ydelta = math.abs(y1 - y2) return xdelta >= ydelta ? (x1 - x2 > 0 ? 'left' : 'right') : (y1 - y2 > 0 ? 'top' : 'bottom') }, move: function(){ var self = this, cidx; self.options.isauto && self.autoplay(); if(++self.curindex == self.size){ self.curindex = 0; self.$container.css(self.getmove()); self.curindex++; } self.settitle(); self.setpages(); cidx = self.curindex == self.size - 1 ? 0 : self.curindex; self.options.onmovebefore.call(self.$container, self.$item, cidx); self.$container.stop(false, true).animate(self.getmove(), self.options.affecttime, function(){ self.options.onmoveafter.call(this, self.$item, cidx) }); }, moveprev: function(flag){ var self = this; if(flag != true){ if(self.options.mode == 'move'){ if(self.curindex == 0){ self.curindex = (self.size - 1); self.$container.css(self.getmove()); } }else{ (self.curindex == 0) && (self.curindex = self.size); } self.curindex--; } self.options.isauto && self.autoplay(); self.settitle(); self.setpages(); self.options.onmovebefore.call(self.$container, self.$item, self.curindex); self.$container.stop(false, true).animate(self.getmove(), self.options.affecttime, function(){ self.options.onmoveafter.call(this, self.$item, self.curindex) }); }, getmove: function(flag){ var move = {}; var size = this.getsize(); var dir = this.options.direction; if(dir == 'top'){ move.top = -this.curindex*size.height; flag && (move.width = size.width); }else{ move.left = -this.curindex*size.width; flag && (move.height = size.height); } return move; }, fade: function(){ var self = this; self.options.isauto && self.autoplay(); self.curindex++; (self.curindex > self.size - 1) && (self.curindex = 0); self.settitle(); self.setpages(); self.options.onmovebefore.call(self.$container, self.$item, self.curindex); self.$item.fadeout(self.options.affecttime) .eq(self.curindex).fadein(self.options.affecttime, function(){ self.options.onmoveafter.call(this, self.$item, self.curindex) }); }, fadeprev: function(flag){ var self = this; if(flag != true){ if(self.options.mode == 'move'){ if(self.curindex == 0){ self.curindex = (self.size - 1); self.$container.css(self.getmove()); } }else{ if(self.curindex == 0){ self.curindex = self.size; } } self.curindex--; } self.options.isauto && self.autoplay(); self.settitle(); self.setpages(); self.options.onmovebefore.call(self.$container, self.$item, self.curindex); self.$item.fadeout(self.options.affecttime) .eq(self.curindex).fadein(self.options.affecttime, function(){ self.options.onmoveafter.call(this, self.$item, self.curindex) }); }, setpages: function(){ if(!this.options.isshowpage || !this.$pages)return; var idx = this.curindex; (idx == this.size - 1 && this.options.mode == 'move') && (idx = 0); $('a', this.$pages).eq(idx).addclass('active').siblings().removeclass('active'); }, settitle: function(){ if(!this.options.isshowtitle || !this.$title)return; var $curitem = this.$item.eq(this.curindex); this.$title.html($.isfunction(this.options.titleattr) ? this.options.titleattr.call($curitem, this.curindex) : $curitem.attr(this.options.titleattr) ); }, setlayout: function(){ var opt = this.options; var css = this.getsetcss(); this.$item.css(css.item) this.$container.css(css.container).wrap(''); this.$wrap = this.$container.parent(); this.$wrap.css(css.wrap); if(this.options.isshowtitle){ this.$title = $('').insertafter(this.$container); this.settitle(); } if(this.options.isshowpage){ this.$pages = $(' ').insertafter(this.$container); this.pagesswitch(); } if(this.options.isshowcontrols){ this.$prev = $('prev'); this.$next = $('next'); this.$container.after(this.$prev.add(this.$next)); this.controlsswitch(); } if(this.options.mode == 'move'){ this.$container.append(this.$item.eq(0).clone().addclass('item-clone')); this.$item = this.$container.find(this.options.item); this.size = this.$item.size(); }else{ this.setfade(); } this.options.oninited.call(this.$container, this.$item, this.options.startslide); }, resize: function(){ var timer, self = this; cleartimeout(timer); timer = settimeout(function(){ self.$wrap.add(self.$item).css(self.getsize(self.options.direction)); self.$container.css(self.getmove(true)); }, 300); }, setfade: function(){ this.$item.hide().eq(this.curindex).show(); }, getsetcss: function(){ var size = this.getsize(), css = {}; var start = math.min(this.options.startslide, this.size); if(this.options.mode == 'fade'){ size.position = 'absolute'; css.height = size.height; css.width = size.width; }else{ if(this.options.direction == 'top'){ css.height = (this.size+1)*100 + '%'; css.width = size.width; css.top = -(start*size.height); }else{ css.height = size.height; css.width = (this.size+1)*100 + '%'; css.left = -(start*size.width); size.float = 'left'; } /*if(this.options.issupporttouch){ if(this.options.direction == 'top'){ css.transform = 'translatey(-'+(start*size.height)+'px)'; }else{ css.transform = 'translatex(-'+(start*size.width)+'px)'; } }else{ if(this.options.direction == 'top'){ css.top = -(start*size.height); }else{ css.left = -(start*size.width); } }*/ css.position = 'relative'; } return { item: size, container: css, wrap: {'overflow': 'hidden', 'position': 'relative', 'width': size.width, 'height': size.height} } }, autoplay: function(){ var self = this; cleartimeout(self.playtimer); self.playtimer = settimeout($.proxy(self, self.options.mode), self.options.intervaltime); }, controlsswitch: function(){ var self = this; this.$next.on('click', $.proxy(self, self.options.mode)); this.$prev.on('click', $.proxy(self, self.options.mode+'prev')); }, pagesswitch: function(){ if(!this.options.isshowpage || !this.$pages)return; var self = this; $('a', this.$pages).on('click', function(){ self.curindex = $(this).index(); self.options.onselected.call(this, self.curindex); self[self.options.mode+'prev'](true); }) }, getpages: function(){ var arr = []; var curindex = this.curindex; $(this.$item).each(function(idx){ var cls = idx == curindex ? 'class="active"' : ''; arr.push(''+(idx+1)+''); }); return arr.join(''); }, getsize: function(){ var $elem = this.$item.eq(0), size; if(this.options.isfullscreen){ size = {width: $(window).width(), height: $(window).height()} }else{ if(this.options.isflexible){ var $elem = this.$wrap ? this.$wrap.parent() : this.$container.parent(); size = this.options.direction == 'top' ? {height: $elem.height()} : {width: $elem.width()} } } return size || {width: $elem.width(), height: $elem.height()} } } $.fn.hislider = function(options){ this.each(function(){ $(this).data('mr.slider', new slider($(this), options)); }); return this; } }(window.jquery))