123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333 |
- /**
- * aui-slide.js 轮播组件
- * @author 流浪男
- * http://www.auicss.com
- * @todo more things to abstract, e.g. Loading css etc.
- * Licensed under the MIT license.
- * http://www.opensource.org/licenses/mit-license.php
- */
- (function(window) {
- "use strict";
- var translateVal,
- firstTouchX,
- firstTouchY,
- touchXDelta,
- handleTranslateVal;
- var touchStartTime; //开始触摸事件
- var offsetX,
- offsetY,
- isScrolling;
- // CLASS 组装
- var CLASS_SLIDER_NODE = "aui-slide-node",
- CLASS_SLIDE_PAGE_WRAP = "aui-slide-page-wrap",
- CLASS_SLIDE_PAGE = "aui-slide-page",
- CLASS_SLIDE_PAGE_ACTIVE = "aui-slide-page-active",
- CLASS_SLIDE_PAGE_DOT = "aui-slide-page-dot",
- CLASS_SLIDE_PAGE_LINE = "aui-slide-page-line";
- var __SLIDER_NODE = "."+CLASS_SLIDER_NODE,
- __SLIDE_PAGE_WRAP = "."+CLASS_SLIDE_PAGE_WRAP,
- __SLIDE_PAGE = "."+CLASS_SLIDE_PAGE,
- __SLIDE_PAGE_ACTIVE = "."+CLASS_SLIDE_PAGE_ACTIVE;
- auiSlide.prototype.options = {
- container:'',
- width:'auto',
- height:'auto',
- speed: 300, //滑动速速
- autoPlay: 0, //自动播放
- pageShow: true, //是否显示分页器
- pageStyle: 'dot',
- dotPosition: 'center',
- friction:1, //阻力
- loop:true,
- currentPage:false,
- PageCount:false
- };
- auiSlide.prototype._init = function(options) {
- extend(this.options, options);
- if(!this.options.container){
- return;
- }
- this.index = 0; //索引值
- this.continuous = true;//用于判断长度为2时的特殊处理
- this.container = this.options.container;
- // console.log(this.options.loop);
- this.loop = this.options.loop;
- this.speed = this.options.speed;
- this.container.style.position = "relative";
- this.container.style.width = this.options.width+"px";
- this.container.style.height = this.options.height+"px";
- var element = this.container.children[0];
- this.slideWrap = element;
- this.slideNodeList = this.slideWrap.querySelectorAll(__SLIDER_NODE);
- if(!element || !this.slideNodeList){
- return;
- }
- // this.options.pageCount(this.slideNodeList.length);
- this.slideWrapWidth = this.slideWrap.offsetWidth;
- this.slideNodeListLength = this.slideNodeList.length;
- if (this.slideNodeListLength == 2) { //当长度为2时作特殊处理
- element.appendChild(this.slideWrap.children[0].cloneNode(true));
- element.appendChild(this.slideWrap.children[1].cloneNode(true));
- this.slideWrap = element;
- this.slideNodeList = this.slideWrap.querySelectorAll(__SLIDER_NODE);
- this.slideNodeListLength = this.slideNodeList.length;
- this.continuous = false;
- }
- for (var i = 0; i < this.slideNodeListLength; i++) {
- this.slideNodeList[i] && (this.slideNodeList[i].style.webkitTransform = this.slideNodeList[i].style.transform = "translate3d("+(this.slideWrapWidth*i)+"px,0,0)");
- }
- if(this.slideNodeListLength > 1) {
- if(this.options.pageShow){
- this.createPagination(0);
- this.setPageDotPosition();
- }
- if(this.options.autoPlay > 500 && this.loop){
- this.autoPlay(0);
- }
- this.slideWrap.addEventListener('touchstart', this.touchStart.bind(this), false);
- this.slideWrap.addEventListener('touchmove', this.touchMove.bind(this), false);
- this.slideWrap.addEventListener('touchend', this.touchEnd.bind(this), false);
- }
- };
- // 当分页器为圆点时位置设置
- auiSlide.prototype.setPageDotPosition = function(){
- var self = this;
- var pageDotPosition = self.options.dotPosition;
- this.container.querySelector(__SLIDE_PAGE_WRAP).style.textAlign = pageDotPosition;
- };
- // 自动播放
- auiSlide.prototype.autoPlay = function (index) {
- var self = this;
- setInterval(function(){
- self.slideTo(self.getCircle(self.index-1), -self.slideWrapWidth, 0);
- self.slideTo(self.getCircle(self.index+2), self.slideWrapWidth, 0);
- self.slideTo(self.index, -self.slideWrapWidth, self.options.speed);
- self.slideTo(self.getCircle(self.index+1), 0, self.options.speed);
- self.index = self.getCircle(self.index+1);
- self.setPaginationActive(self.index);
- }, self.options.autoPlay)
- };
- // 设置当前分页
- auiSlide.prototype.setPaginationActive = function(index){
- var self = this;
- if(self.options.currentPage){
- self.options.currentPage(index);
- }
- if(!this.container.querySelector(__SLIDE_PAGE_WRAP)){
- return;
- }
- var pageList = this.container.querySelectorAll(__SLIDE_PAGE);
- if(this.container.querySelector(__SLIDE_PAGE+__SLIDE_PAGE_ACTIVE)){
- this.container.querySelector(__SLIDE_PAGE+__SLIDE_PAGE_ACTIVE).classList.remove(CLASS_SLIDE_PAGE_ACTIVE);
- }
- if(!this.continuous){
- if(this.index == 3){
- pageList[1].classList.add(CLASS_SLIDE_PAGE_ACTIVE);
- }else if(this.index==2){
- pageList[0].classList.add(CLASS_SLIDE_PAGE_ACTIVE);
- }else{
- pageList[this.index].classList.add(CLASS_SLIDE_PAGE_ACTIVE);
- }
- }else{
- pageList[this.index].classList.add(CLASS_SLIDE_PAGE_ACTIVE);
- }
- };
- // 创建分页器
- auiSlide.prototype.createPagination = function(index){
- var self = this;
- var pageWrap = this.container.querySelector(__SLIDE_PAGE_WRAP);
- if(!pageWrap){
- return;
- }
- pageWrap.innerHTML = '';
- var pageShowHtml = '';
- switch (self.options.pageStyle) {
- case "dot":// 原点
- if (!this.continuous) {
- for (var i = 0; i < 2; i++) {
- pageShowHtml += '<span class="'+CLASS_SLIDE_PAGE+' '+CLASS_SLIDE_PAGE_DOT+'"></span>';
- }
- }else{
- for (var i = 0; i < this.slideNodeListLength; i++) {
- pageShowHtml += '<span class="'+CLASS_SLIDE_PAGE+' '+CLASS_SLIDE_PAGE_DOT+'"></span>';
- }
- }
- pageWrap.innerHTML = pageShowHtml;
- self.setPaginationActive(0);
- break;
- case "line":// 线条
- if (!this.continuous) {
- for (var i = 0; i < 2; i++) {
- pageShowHtml += '<span class="'+CLASS_SLIDE_PAGE+' '+CLASS_SLIDE_PAGE_LINE+'" style="width:50%"></span>';
- }
- }else{
- for (var i = 0; i < this.slideNodeListLength; i++) {
- pageShowHtml += '<span class="'+CLASS_SLIDE_PAGE+' '+CLASS_SLIDE_PAGE_LINE+'" style="width:'+(100/this.slideNodeListLength)+'%"></span>';
- }
- }
- pageWrap.innerHTML = pageShowHtml;
- self.setPaginationActive(0);
- break;
- }
- };
- // 总页数
- auiSlide.prototype.pageCount = function() {
- var self = this;
- return self.slideNodeList.length;
- };
- auiSlide.prototype.touchStart = function(event) {
- touchStartTime = new Date() * 1;
- firstTouchX = parseInt(event.changedTouches[0].pageX);
- firstTouchY = parseInt(event.changedTouches[0].pageY);
- isScrolling = undefined;
- };
- auiSlide.prototype.touchMove = function(event) {
- var touchMoveObj = event.changedTouches[0],
- touchX = parseInt(touchMoveObj.pageX);
- touchXDelta = touchX - firstTouchX;
- handleTranslateVal = touchXDelta/this.options.friction;
- // 滑动位移
- offsetX = parseInt(touchMoveObj.pageX) - firstTouchX;
- offsetY = parseInt(touchMoveObj.pageY) - firstTouchY;
- var direction = this.getDirection(offsetX,offsetY);
- if ( typeof isScrolling == 'undefined') {
- isScrolling = !!( isScrolling || Math.abs(offsetX) < Math.abs(offsetY) );
- }
- if(!isScrolling){
- event.preventDefault();
- if(!this.loop){ //不循环
- if(!this.continuous && this.index==1 && direction=='left'){
- return;
- }
- if(!this.continuous && this.index==0 && direction=='right'){
- return;
- }
- if(this.index == this.slideNodeList.length-1){
- if(handleTranslateVal <= 0){
- return;
- }
- this.setTranslate(this.getCircle(this.index-1), handleTranslateVal - this.slideWrapWidth, 0);
- }else if(this.index == 0){
- if(handleTranslateVal >= 0){
- return;
- }
- this.setTranslate(this.getCircle(this.index+1), this.slideWrapWidth, 0);
- }
- }
- this.setTranslate(this.getCircle(this.index-1), handleTranslateVal - this.slideWrapWidth, 0);
- this.setTranslate(this.index, handleTranslateVal , 0);
- this.setTranslate(this.getCircle(this.index+1), handleTranslateVal + this.slideWrapWidth, 0);
- }
- };
- auiSlide.prototype.touchEnd = function(event) {
- var touchEndObj = event.changedTouches[0];
- var touchEndX = parseInt(touchEndObj.pageX) - firstTouchX;
- var touchEndY = parseInt(touchEndObj.pageY) - firstTouchY;
- var touchEndxy = {
- x: touchEndObj.pageX || 0,
- y: touchEndObj.pageY || 0
- };
- var moveDirection = this.getDirection(touchEndX,touchEndY); //滑动方向
- var boundary = this.slideWrapWidth/4;
- var duration = (new Date() * 1) - touchStartTime;
- var isValid = Number(duration) < 250 && Math.abs(offsetX) > 20 || Math.abs(offsetX) > boundary;
- if (isScrolling) {
- return;
- }
- if(isValid){
- if(offsetX < 0){
- if(!this.loop && this.index == this.slideNodeList.length-1){
- return;
- }
- if(!this.loop && !this.continuous && this.index==1){
- return;
- }
- if(offsetX < -boundary && moveDirection == 'left'){
- // left
- this.slideTo(this.getCircle(this.index-1), -this.slideWrapWidth, 0);
- this.slideTo(this.getCircle(this.index+2), this.slideWrapWidth, 0);
- this.slideTo(this.index, -this.slideWrapWidth, this.speed);
- this.slideTo(this.getCircle(this.index+1), 0, this.speed);
- this.index = this.getCircle(this.index+1);
- }else{
- // this.slideTo(this.getCircle(this.index-1), -this.slideWrapWidth, this.speed);
- this.slideTo(this.index, 0, this.speed);
- this.slideTo(this.getCircle(this.index+1), this.slideWrapWidth, this.speed);
- }
- }else if(offsetX > 0){
- if(!this.loop && this.index == 0){
- return;
- }
- if(!this.loop && !this.continuous && this.index==0){
- return;
- }
- if(offsetX > boundary && moveDirection == 'right'){
- // right
- this.slideTo(this.getCircle(this.index+1), this.slideWrapWidth, 0);
- this.slideTo(this.getCircle(this.index-2), -this.slideWrapWidth, 0);
- this.slideTo(this.index, this.slideWrapWidth, this.speed);
- this.slideTo(this.getCircle(this.index-1), 0, this.speed);
- this.index = this.getCircle(this.index-1);
- }else{
- // this.slideTo(this.getCircle(this.index-1), -this.slideWrapWidth, this.speed);
- this.slideTo(this.index, 0, this.speed);
- this.slideTo(this.getCircle(this.index+1), this.slideWrapWidth, this.speed);
- }
- }
- }else{
- if(offsetX){
- this.slideTo(this.getCircle(this.index-1), -this.slideWrapWidth, this.speed);
- this.slideTo(this.index, 0, this.speed);
- this.slideTo(this.getCircle(this.index+1), this.slideWrapWidth, this.speed);
- }
- }
- this.setPaginationActive(this.index);
- };
- auiSlide.prototype.setTranslate = function (index,dist,speed){
- if(this.slideNodeList[index]){
- this.slideNodeList[index].style.webkitTransitionDuration =
- this.slideNodeList[index].style.transitionDuration = speed + 'ms';
- this.slideNodeList[index].style.webkitTransform =
- this.slideNodeList[index].style.transform = "translate3d("+dist+"px,0,0)";
- }
- };
- auiSlide.prototype.slideTo = function (index, dist, speed) {
- this.setTranslate(index, dist, speed);
- // index = dist;
- };
- auiSlide.prototype.getCircle = function (index) {
- return (this.slideNodeListLength + (index % this.slideNodeListLength)) % this.slideNodeListLength;
- };
- auiSlide.prototype.getDirection = function(x, y) {
- if (x === y) { return '';}
- if (Math.abs(x) >= Math.abs(y)) {
- return x > 0 ? 'right' : 'left';
- } else {
- return y > 0 ? 'down' : 'up';
- }
- }
- function extend (a, b) {
- for (var key in b) {
- if (b.hasOwnProperty(key)) {
- a[key] = b[key];
- }
- }
- return a;
- }
- function auiSlide (options) {
- this._init(options);
- }
- window.auiSlide = auiSlide;
- })(window);
|