mobile轮播组件——支持事件回调和队列(原生js实现)

mobile轮播组件,支持图片不定高,支持事件回调,队列,兼容主流webkit浏览器

demo地址:http://7li.github.io/components/swipe/

demo二维码:

测试地址:http://7li.github.io/components/swipe/test/

仓库地址:https://github.com/7LI/swipe

本文出自:http://blog.csdn.net/nancle/article/details/44937531

仓促之际必有疏漏,请各位同仁批评指正

源码

/*
 * Swipe 1.0.0
 *
 * Liu Yanzhi
 * 702368372atqqcom
 * Copyright 2015, MIT License
 *
 * Thanks to: https://github.com/thebird
 */
define(function() {
  var TEST = document.getElementById('test');
  function test(str) {
    TEST.innerHTML = str;
  }
  function Swipe(container, option) {
    this.container = container;
    this.wrap = this.container.children[0];
    this.slides = this.wrap.children;
    this.length = this.slides.length;

    if (!option) option = {};
    this.option = option;
    this.speed = option.speed || 300;
    this.threshould = option.threshould || 90;
    this.auto = option.auto || 2000;
    this.index = 0;
    this.offset = 0;
    this.classes = {
      nav: 'swipe-nav',
      navItem: 'swipe-nav-item',
      navOn: 'swipe-nav-item-on'
    };
    this.queue = [];

    this.setup();
    this.bind();

    this.set('nav', option.nav !== false);
    this.set('auto', option.auto !== 0);
  }

  Swipe.prototype.setup = function() {
    this.width = this.container.offsetWidth;

    // Set container
    this.container.style.overflow = 'hidden';
    this.container.style.position = 'relative';

    // Set wrap
    this.wrap.style.position = 'relative';
    this.wrap.style.overflow = 'visible';
    this.wrap.style.height = 'auto';
    // this.wrap.style.width = '99999999px';
    this.wrap.style.webkitTransform = '';

    // Set slides
    for(var i = 0; i < this.length; i++) {
      var slide = this.slides[i];
      slide.style.position = 'relative';
      slide.style.float = 'left';
      slide.style.height = 'auto';
      slide.style.width = this.width + 'px';
      slide.offset = i * this.width;
      slide.style.webkitTransform = '';
    }
  }

  Swipe.prototype.slideTo = function(index, callback, direction, queue) {
    // Handling muti-arguments
    if (index > this.length - 1) index = this.length - 1;
    if (index < 0) index = 0;
    if (typeof callback != 'function' && callback != null) {
      queue = direction;
      direction = callback;
      callback = null;
    };
    if (typeof direction != 'string') {
      queue = direction;
      direction = 'right';
    }

    // Not sliding and not enqueue, so do nothing
    if (this.sliding && !queue) return;

    // Sliding, so enqueque
    if (this.sliding && queue) {
      var slide = {
        index: index,
        callback: callback,
        direction: direction
      }
      this.queue.push(slide);
      return;
    }

    // Not sliding, so enforce slide
    if (index == this.index) {
      // Current index, no need to transition, immediately trigger callback
      callback && callback();
      this.nav && this.setNav();
      this.dequeue();
      return;
    }

    this.sliding = true;
    this.callback = callback;

    var offset;
    // Relocate slides
    this.relocateSlides(direction);
    // Relocate wrap
    offset =  this.slides[this.index].offset - this.slides[index].offset;
    offset += this.offset;

    this.offset = offset;
    this.index = index;

    var style = this.wrap.style;
    style.webkitTransitionDuration = this.speed + 'ms';
    style.webkitTransform = 'translate3D(' + offset + 'px, 0px, 0px)';
  }

  Swipe.prototype.relocateSlides = function(direction) {
    var currentSlide = this.slides[this.index];
    for (var i = 0; i < this.length; i++) {
      if (i == this.index) continue;

      var slide = this.slides[i];
      if (direction == 'right') {
        if (slide.offset < currentSlide.offset) {
          slide.offset += this.width * this.length;
          var calculateOffset = slide.offset - this.width * i;
          slide.style.webkitTransitionDuration = 0;
          slide.style.webkitTransform = 'translate3D(' + calculateOffset + 'px, 0px, 0px)';
        }
      } else if (direction == 'left') {
        if (slide.offset > currentSlide.offset) {
          slide.offset -= this.width * this.length;
          var calculateOffset = slide.offset - this.width * i;
          slide.style.webkitTransitionDuration = 0;
          slide.style.webkitTransform = 'translate3D(' + calculateOffset + 'px, 0px, 0px)';
        }
      }
    }
  }

  Swipe.prototype.prev = function(callback, queue) {
    // Handling muti-arguments
    if (typeof callback != 'function') { queue = callback; callback = null };

    var index = this.getIndex(queue);
    if (index <= 0) {
      index = this.length - 1;
    } else {
      index = index - 1;
    }
    this.slideTo(index, callback, 'left', queue);
  }

  Swipe.prototype.next = function(callback, queue) {
    // Handling muti-arguments
    if (typeof callback != 'function') { queue = callback; callback = null };

    var index = this.getIndex(queue);
    if (index >= this.length - 1) {
      index = 0;
    } else {
      index = index + 1;
    }

    this.slideTo(index, callback, 'right', queue);
  }

  Swipe.prototype.stop = function() {
    return this;
  }

  Swipe.prototype.bind = function() {
    var that = this;
    var start, delta;
    this.events = {
      handleEvent: function(e) {
        switch (e.type) {
            case 'touchstart':
              var touches = e.touches[0];
              start = {
                x: touches.pageX,
                y: touches.pageY,
              };
              delta = {x: 0, y: 0};
              that.container.addEventListener('touchmove', that.events);
              that.wrap.addEventListener('touchend', that.events);
              that.autoplay(false);
              break;
            case 'touchmove':
              // prevent native scrolling
              e.preventDefault();

              var touches = e.touches[0];
              delta = {
                x: touches.pageX - start.x,
                y: touches.pageY - start.y
              }
              var direction = delta.x > 0 ? 'left' : 'right';
              that.relocateSlides(direction);
              that.attempSlide(delta);
              break;
            case 'touchend':
              if (Math.abs(delta.x) > that.threshould) {
                if (delta.x > 0) {
                  that.prev();
                } else {
                  that.next();
                }
              } else {
                that.cancelSlide();
              }
              that.container.removeEventListener('touchmove', that.events);
              that.container.removeEventListener('touchend', that.events);
              that.autoplay(that.option.auto !== 0);
              break;
            case 'transitionend':
            case 'webkitTransitionEnd':
              if (e.propertyName != '-webkit-transform' &&
                  e.propertyName != 'transform') return;

              that.sliding = false;
              that.nav && that.setNav(); // Set nav
              that.callback && that.callback();
              // Enforce the next slide in queue
              that.dequeue();
              break;
            case 'resize':
              that.resize();
            break;
         }
      }
    }
    this.container.addEventListener('transitionend', this.events, false);
    this.container.addEventListener('webkitTransitionEnd', this.events, false);
    this.container.addEventListener('touchstart', this.events);
    window.addEventListener('resize', this.events);
  }

  Swipe.prototype.resize = function() {
    this.setup();
    this.relocateSlides('right');
    // Relocate wrap
    this.offset =  -this.slides[this.index].offset;
    var style = this.wrap.style;
    style.webkitTransitionDuration = '0ms';
    style.webkitTransform = 'translate3D(' + this.offset + 'px, 0px, 0px)';
  }

  Swipe.prototype.dequeue = function() {
     var nextSlide = this.queue.shift();
     nextSlide && this.slideTo(nextSlide.index, nextSlide.callback);
  }

  Swipe.prototype.getIndex = function(queue) {
    var index = this.index;
    if (queue) {
      var lastSlide = this.queue[this.queue.length - 1];
      if (lastSlide) index = lastSlide.index;
    };
    return index;
  }

  Swipe.prototype.set = function(key, value) {
    switch (key) {
      case 'nav':
        if (!this.nav) {
          this.createNav();
        }
        if (value == true) {
          this.nav.style.display = 'block';
          this.setNav();
        } else {
          this.nav.style.display = 'none';
        }
        break;
      case 'auto':
        this.autoplay(value);
        break;
    }
  }

  Swipe.prototype.attempSlide = function(delta) {
    if (this.sliding) return;

    var style = this.wrap.style;
    style.webkitTransitionDuration = '0ms';
    var offset = this.offset + delta.x;
    style.webkitTransform = 'translate3D(' + offset + 'px, 0px, 0px)';
  }

  Swipe.prototype.cancelSlide = function() {
    var style = this.wrap.style;
    style.webkitTransitionDuration = this.speed + 'ms';
    style.webkitTransform = 'translate3D(' + this.offset + 'px, 0px, 0px)';
  }

  Swipe.prototype.createNav = function() {
    this.nav = document.createElement('div');
    this.nav.className = this.classes.nav;
    for (var i = 0; i < this.length; i++) {
      var navItem = document.createElement('span');
      navItem.className = this.classes.navItem;
      this.nav.appendChild(navItem);
    }
    this.container.appendChild(this.nav);
  }

  Swipe.prototype.setNav = function() {
    for (var i = 0; i < this.length; i++) {
      this.nav.children[i].classList.remove(this.classes.navOn);
    }
    this.nav.children[this.index].classList.add(this.classes.navOn);
  }

  Swipe.getLength = function() {
    return this.length;
  }

  Swipe.prototype.autoplay = function(onOff) {
    if (this.auto == 0) return;

    clearInterval(this.timer);
    var that = this;
    if (onOff) {
      this.timer = setInterval(function() {
        that.next();
      }, this.auto);
    }
  }

  Swipe.prototype.kill = function() {
    this.container.removeChild(this.nav);
    this.container.removeEventListener('transitionend', this.events);
    this.container.removeEventListener('touchstart', this.events);
  }

  Swipe.v = Swipe.version = '1.0.0';
  return Swipe;
})
时间: 2024-08-24 04:18:48

mobile轮播组件——支持事件回调和队列(原生js实现)的相关文章

移动端轮播组件swipeslide实现

从前只做过PC端轮播组件,实现方式也是margin负值和setTimeout.前一阵看到一个比较精简的移动端轮播组件的实现https://github.com/ximan/swipeSlide/blob/gh-pages/js/swipeSlide.js,用translate代替margin负值,并且添加了对touch事件的处理.在这里总结一下这个组件的实现. 所有的li绝对定位于容器左上角,宽度100%,高度100%. 1.组件init步骤: 1)如果设定了连续轮播,则复制first slid

MUI组件四:选择器、滚动条、单选框、区域滚动和轮播组件

目录(?)[+] 1.picker(选择器) mui框架扩展了pipcker组件,可用于弹出选择器,在各平台上都有统一表现.poppicker和dtpicker是对picker的具体实现.*poppicker组件依赖mui.picker.js/.css mui.poppicker.js/.css请务必在mui.js/css后中引用,也可统一引用 压缩版本:mui.picker.min.js (1).popPicker 适用于弹出单级或多级选择器 a.通过new mui.PopPicker()初始

vue中引入awesomeswiper的方法以及编写轮播组件

1.先安装less-loader npm install less less-loader --save 2.再安装css-loader npm install css-loader --save 3.安装上面两个之后.再安装vue-awesome-swiper(必须在前两个安装过之后安装) npm install vue-awesome-swiper --save 4.安装完之后在package.json文件中查看一下,看是否安装上,如果安装成功,里面会显示对应的版本号 "less"

bootstrap轮播组件,大屏幕图片居中效果

在慕课网学习bootstrap轮播组件的时候,了解到轮播的图片都放在了类名为item下的img中 视频中老师对图片自适应采用给图片img设置width=100%完成,然而这样自适应处理图片在不同屏幕中效果不同,大屏效果非常糟糕.比如 这样一张图片, 为了图片自适应设置width=100%,在宽1920px下显示效果是这样的 显然,因为图片设置了100%的宽度,其大部分内容被截去,显示非常糟糕. 后来想了想.有没有办法可以让图片真正的自适应呢并且居中呢,于是想到了css3背景图片属性backgro

基于Reactive Native轮播组件的应用开发以及移动端模拟器下的调试

总结下这段时间学习reactive native的一些东西,我们来认识一下,被炒得这么火的rn,究竟是个什么东西,以及如何去搭建自己的demo. reactive  native是什么 由facebook开发的一种应用框架,可以用react开发原生应用的框架.简单来说就是可以通过js和react来开发的一种框架. react是什么 一套js的框架,也是facebook开源.特点:jsx语法(类似XML),组件化模式,virtual DOM,单向数据流. 基本模式:每个react应用可视为组件的组

【AmazeUI】图片轮播组件

这个组件在IE上一直很火,其实现可以参考<[JavaScript]原生态兼容IE6的图片轮播>(点击打开链接),AmazeUI同样在移动端提供这样的组件. 其效果如下,这个结果要在谷歌.野狐禅等浏览器的手机端调试模式才能看到,在PC端会布局错乱. 用户可以自由滑动,点击下方的圆点,选择自己要浏览的图片,当鼠标悬停在图片上,其组件则不会继续轮播图片. 实现代码如下: <!--使用HTML5开发--> <!doctype html> <html class="

移动端Reactive Native轮播组件

移动端Reactive Native轮播组件 总结下这段时间学习reactive native的一些东西,我们来认识一下,被炒得这么火的rn,究竟是个什么东西,以及如何去搭建自己的demo. reactive  native是什么 由facebook开发的一种应用框架,可以用react开发原生应用的框架.简单来说就是可以通过js和react来开发的一种框架. react是什么 一套js的框架,也是facebook开源.特点:jsx语法(类似XML),组件化模式,virtual DOM,单向数据流

jq轮播图支持ie7

用过一些轮播框架  但是有的不正常ie7 所以就自己找资料写了一个 代码不粗糙的 <!DOCTYPE html><html><head><title>轮播图支持ie7依赖jq</title><meta charset="utf-8" /><script src="http://libs.baidu.com/jquery/1.7.2/jquery.min.js"></script

vue-awesome-swipe 基于vue使用的轮播组件 使用

npm install vue-awesome-swiper --save  //基于vue使用的轮播组件 <template> <swiper :options="swiperOption" ref="mySwiper"> <swiper-slide v-for="(banner,index) in banners" :key="index"> <img v-if="ban