zoukankan      html  css  js  c++  java
  • swipe.js

    swipe插件真的是好简单,看代码就知道了

    先把swipe.js放上来,有空再拜读一下,看能否理解

    /*
     * Swipe 2.0
     *
     * Brad Birdsall
     * Copyright 2013, MIT License
     *
    */
    
    function Swipe(container, options) {
    
      "use strict";
    
      // utilities
      var noop = function() {}; // simple no operation function
      var offloadFn = function(fn) { setTimeout(fn || noop, 0) }; // offload a functions execution
    
      // check browser capabilities
      var browser = {
        addEventListener: !!window.addEventListener,
        touch: ('ontouchstart' in window) || window.DocumentTouch && document instanceof DocumentTouch,
        transitions: (function(temp) {
          var props = ['transitionProperty', 'WebkitTransition', 'MozTransition', 'OTransition', 'msTransition'];
          for ( var i in props ) if (temp.style[ props[i] ] !== undefined) return true;
          return false;
        })(document.createElement('swipe'))
      };
    
      // quit if no root element
      if (!container) return; //如果不存在元素 则返回
      var element = container.children[0]; //元素的第一个,如果有多个,可以修改
      var slides, slidePos, width, length; //
      options = options || {}; //参数为空的话就赋值一个空的对象给options
      var index = parseInt(options.startSlide, 10) || 0; //开始显示第几个图片或者元素,默认为0
      var speed = options.speed || 300; //速度
      options.continuous = options.continuous !== undefined ? options.continuous : true;//默认为true
    
      function setup() {
    
        // cache slides
        slides = element.children; //获取子元素
        length = slides.length; //子元素长度
    
        // set continuous to false if only one slide
        if (slides.length < 2) options.continuous = false; //如果少于2个,则不需要滚动
    
        //special case if two slides
        if (browser.transitions && options.continuous && slides.length < 3) {
          element.appendChild(slides[0].cloneNode(true));
          element.appendChild(element.children[1].cloneNode(true));
          slides = element.children;
        }
    
        // create an array to store current positions of each slide
        slidePos = new Array(slides.length);
    
        // determine width of each slide
        width = container.getBoundingClientRect().width || container.offsetWidth;
    
        element.style.width = (slides.length * width) + 'px';
    
        // stack elements
        var pos = slides.length;
        while(pos--) {
    
          var slide = slides[pos];
    
          slide.style.width = width + 'px';
          slide.setAttribute('data-index', pos);
    
          if (browser.transitions) {
            slide.style.left = (pos * -width) + 'px';
            move(pos, index > pos ? -width : (index < pos ? width : 0), 0);
          }
    
        }
    
        // reposition elements before and after index
        if (options.continuous && browser.transitions) {
          move(circle(index-1), -width, 0);
          move(circle(index+1), width, 0);
        }
    
        if (!browser.transitions) element.style.left = (index * -width) + 'px';
    
        container.style.visibility = 'visible';
    
      }
    
      function prev() {
    
        if (options.continuous) slide(index-1);
        else if (index) slide(index-1);
    
      }
    
      function next() {
    
        if (options.continuous) slide(index+1);
        else if (index < slides.length - 1) slide(index+1);
    
      }
    
      function circle(index) {
    
        // a simple positive modulo using slides.length
        return (slides.length + (index % slides.length)) % slides.length;
    
      }
    
      function slide(to, slideSpeed) {
    
        // do nothing if already on requested slide
        if (index == to) return;
    
        if (browser.transitions) {
    
          var direction = Math.abs(index-to) / (index-to); // 1: backward, -1: forward
    
          // get the actual position of the slide
          if (options.continuous) {
            var natural_direction = direction;
            direction = -slidePos[circle(to)] / width;
    
            // if going forward but to < index, use to = slides.length + to
            // if going backward but to > index, use to = -slides.length + to
            if (direction !== natural_direction) to =  -direction * slides.length + to;
    
          }
    
          var diff = Math.abs(index-to) - 1;
    
          // move all the slides between index and to in the right direction
          while (diff--) move( circle((to > index ? to : index) - diff - 1), width * direction, 0);
    
          to = circle(to);
    
          move(index, width * direction, slideSpeed || speed);
          move(to, 0, slideSpeed || speed);
    
          if (options.continuous) move(circle(to - direction), -(width * direction), 0); // we need to get the next in place
    
        } else {
    
          to = circle(to);
          animate(index * -width, to * -width, slideSpeed || speed);
          //no fallback for a circular continuous if the browser does not accept transitions
        }
    
        index = to;
        offloadFn(options.callback && options.callback(index, slides[index]));
      }
    
      function move(index, dist, speed) {
    
        translate(index, dist, speed);
        slidePos[index] = dist;
    
      }
    
      function translate(index, dist, speed) {
    
        var slide = slides[index];
        var style = slide && slide.style;
    
        if (!style) return;
    
        style.webkitTransitionDuration =
        style.MozTransitionDuration =
        style.msTransitionDuration =
        style.OTransitionDuration =
        style.transitionDuration = speed + 'ms';
    
        style.webkitTransform = 'translate(' + dist + 'px,0)' + 'translateZ(0)';
        style.msTransform =
        style.MozTransform =
        style.OTransform = 'translateX(' + dist + 'px)';
    
      }
    
      function animate(from, to, speed) {
    
        // if not an animation, just reposition
        if (!speed) {
    
          element.style.left = to + 'px';
          return;
    
        }
    
        var start = +new Date;
    
        var timer = setInterval(function() {
    
          var timeElap = +new Date - start;
    
          if (timeElap > speed) {
    
            element.style.left = to + 'px';
    
            if (delay) begin();
    
            options.transitionEnd && options.transitionEnd.call(event, index, slides[index]);
    
            clearInterval(timer);
            return;
    
          }
    
          element.style.left = (( (to - from) * (Math.floor((timeElap / speed) * 100) / 100) ) + from) + 'px';
    
        }, 4);
    
      }
    
      // setup auto slideshow
      var delay = options.auto || 0;
      var interval;
    
      function begin() {
    
        interval = setTimeout(next, delay);
    
      }
    
      function stop() {
    
        delay = 0;
        clearTimeout(interval);
    
      }
    
    
      // setup initial vars
      var start = {};
      var delta = {};
      var isScrolling;
    
      // setup event capturing
      var events = {
    
        handleEvent: function(event) {
    
          switch (event.type) {
            case 'touchstart': this.start(event); break;
            case 'touchmove': this.move(event); break;
            case 'touchend': offloadFn(this.end(event)); break;
            case 'webkitTransitionEnd':
            case 'msTransitionEnd':
            case 'oTransitionEnd':
            case 'otransitionend':
            case 'transitionend': offloadFn(this.transitionEnd(event)); break;
            case 'resize': offloadFn(setup); break;
          }
    
          if (options.stopPropagation) event.stopPropagation();
    
        },
        start: function(event) {
    
          var touches = event.touches[0];
    
          // measure start values
          start = {
    
            // get initial touch coords
            x: touches.pageX,
            y: touches.pageY,
    
            // store time to determine touch duration
            time: +new Date
    
          };
    
          // used for testing first move event
          isScrolling = undefined;
    
          // reset delta and end measurements
          delta = {};
    
          // attach touchmove and touchend listeners
          element.addEventListener('touchmove', this, false);
          element.addEventListener('touchend', this, false);
    
        },
        move: function(event) {
    
          // ensure swiping with one touch and not pinching
          if ( event.touches.length > 1 || event.scale && event.scale !== 1) return
    
          if (options.disableScroll) event.preventDefault();
    
          var touches = event.touches[0];
    
          // measure change in x and y
          delta = {
            x: touches.pageX - start.x,
            y: touches.pageY - start.y
          }
    
          // determine if scrolling test has run - one time test
          if ( typeof isScrolling == 'undefined') {
            isScrolling = !!( isScrolling || Math.abs(delta.x) < Math.abs(delta.y) );
          }
    
          // if user is not trying to scroll vertically
          if (!isScrolling) {
    
            // prevent native scrolling
            event.preventDefault();
    
            // stop slideshow
            stop();
    
            // increase resistance if first or last slide
            if (options.continuous) { // we don't add resistance at the end
    
              translate(circle(index-1), delta.x + slidePos[circle(index-1)], 0);
              translate(index, delta.x + slidePos[index], 0);
              translate(circle(index+1), delta.x + slidePos[circle(index+1)], 0);
    
            } else {
    
              delta.x =
                delta.x /
                  ( (!index && delta.x > 0               // if first slide and sliding left
                    || index == slides.length - 1        // or if last slide and sliding right
                    && delta.x < 0                       // and if sliding at all
                  ) ?
                  ( Math.abs(delta.x) / width + 1 )      // determine resistance level
                  : 1 );                                 // no resistance if false
    
              // translate 1:1
              translate(index-1, delta.x + slidePos[index-1], 0);
              translate(index, delta.x + slidePos[index], 0);
              translate(index+1, delta.x + slidePos[index+1], 0);
            }
    
          }
    
        },
        end: function(event) {
    
          // measure duration
          var duration = +new Date - start.time;
    
          // determine if slide attempt triggers next/prev slide
          var isValidSlide =
                Number(duration) < 250               // if slide duration is less than 250ms
                && Math.abs(delta.x) > 20            // and if slide amt is greater than 20px
                || Math.abs(delta.x) > width/2;      // or if slide amt is greater than half the width
    
          // determine if slide attempt is past start and end
          var isPastBounds =
                !index && delta.x > 0                            // if first slide and slide amt is greater than 0
                || index == slides.length - 1 && delta.x < 0;    // or if last slide and slide amt is less than 0
    
          if (options.continuous) isPastBounds = false;
    
          // determine direction of swipe (true:right, false:left)
          var direction = delta.x < 0;
    
          // if not scrolling vertically
          if (!isScrolling) {
    
            if (isValidSlide && !isPastBounds) {
    
              if (direction) {
    
                if (options.continuous) { // we need to get the next in this direction in place
    
                  move(circle(index-1), -width, 0);
                  move(circle(index+2), width, 0);
    
                } else {
                  move(index-1, -width, 0);
                }
    
                move(index, slidePos[index]-width, speed);
                move(circle(index+1), slidePos[circle(index+1)]-width, speed);
                index = circle(index+1);
    
              } else {
                if (options.continuous) { // we need to get the next in this direction in place
    
                  move(circle(index+1), width, 0);
                  move(circle(index-2), -width, 0);
    
                } else {
                  move(index+1, width, 0);
                }
    
                move(index, slidePos[index]+width, speed);
                move(circle(index-1), slidePos[circle(index-1)]+width, speed);
                index = circle(index-1);
    
              }
    
              options.callback && options.callback(index, slides[index]);
    
            } else {
    
              if (options.continuous) {
    
                move(circle(index-1), -width, speed);
                move(index, 0, speed);
                move(circle(index+1), width, speed);
    
              } else {
    
                move(index-1, -width, speed);
                move(index, 0, speed);
                move(index+1, width, speed);
              }
    
            }
    
          }
    
          // kill touchmove and touchend event listeners until touchstart called again
          element.removeEventListener('touchmove', events, false)
          element.removeEventListener('touchend', events, false)
    
        },
        transitionEnd: function(event) {
    
          if (parseInt(event.target.getAttribute('data-index'), 10) == index) {
    
            if (delay) begin();
    
            options.transitionEnd && options.transitionEnd.call(event, index, slides[index]);
    
          }
    
        }
    
      }
    
      // trigger setup
      setup();
    
      // start auto slideshow if applicable
      if (delay) begin();
    
    
      // add event listeners
      if (browser.addEventListener) {
    
        // set touchstart event on element
        if (browser.touch) element.addEventListener('touchstart', events, false);
    
        if (browser.transitions) {
          element.addEventListener('webkitTransitionEnd', events, false);
          element.addEventListener('msTransitionEnd', events, false);
          element.addEventListener('oTransitionEnd', events, false);
          element.addEventListener('otransitionend', events, false);
          element.addEventListener('transitionend', events, false);
        }
    
        // set resize event on window
        window.addEventListener('resize', events, false);
    
      } else {
    
        window.onresize = function () { setup() }; // to play nice with old IE
    
      }
    
      // expose the Swipe API
      return {
        setup: function() {
    
          setup();
    
        },
        slide: function(to, speed) {
    
          // cancel slideshow
          stop();
    
          slide(to, speed);
    
        },
        prev: function() {
    
          // cancel slideshow
          stop();
    
          prev();
    
        },
        next: function() {
    
          // cancel slideshow
          stop();
    
          next();
    
        },
        stop: function() {
    
          // cancel slideshow
          stop();
    
        },
        getPos: function() {
    
          // return current index position
          return index;
    
        },
        getNumSlides: function() {
    
          // return total number of slides
          return length;
        },
        kill: function() {
    
          // cancel slideshow
          stop();
    
          // reset element
          element.style.width = '';
          element.style.left = '';
    
          // reset slides
          var pos = slides.length;
          while(pos--) {
    
            var slide = slides[pos];
            slide.style.width = '';
            slide.style.left = '';
    
            if (browser.transitions) translate(pos, 0, 0);
    
          }
    
          // removed event listeners
          if (browser.addEventListener) {
    
            // remove current event listeners
            element.removeEventListener('touchstart', events, false);
            element.removeEventListener('webkitTransitionEnd', events, false);
            element.removeEventListener('msTransitionEnd', events, false);
            element.removeEventListener('oTransitionEnd', events, false);
            element.removeEventListener('otransitionend', events, false);
            element.removeEventListener('transitionend', events, false);
            window.removeEventListener('resize', events, false);
    
          }
          else {
    
            window.onresize = null;
    
          }
    
        }
      }
    
    }
    
    
    if ( window.jQuery || window.Zepto ) {
      (function($) {
        $.fn.Swipe = function(params) {
          return this.each(function() {
            $(this).data('Swipe', new Swipe($(this)[0], params));
          });
        }
      })( window.jQuery || window.Zepto )
    }

    接着再将使用方法放上来

    <!DOCTYPE HTML> 
    <html>
    <head>
    <title>Swipe 2</title>
    <meta http-equiv="X-UA-Compatible" content="IE=8">
    <meta name='viewport' content='width=device-width, initial-scale=1.0, maximum-scale=1.0'/> 
    <style>
    
    /* Swipe 2 required styles */
    
    .swipe {
      overflow: hidden;
      visibility: hidden;
      position: relative;
    }
    .swipe-wrap {
      overflow: hidden;
      position: relative;
    }
    .swipe-wrap > div {
      float:left;
      width:100%;
      position: relative;
    }
    .swipe-wrap > div a img{width:100%; height:180px;border:0px;}
    /* END required styles */
    </style>
    
    </head>
    <body>
    <div id='mySwipe' style='100%; height:180px;' class='swipe'>
      <div class='swipe-wrap'>
        <div><a href=""><img src="images/1.png" /></a></div>
        <div><a href=""><img src="images/2.png" /></a></div>
        <div><a href=""><img src="images/3.png" /></a></div>
        <div><a href=""><img src="images/4.png" /></a></div>
      </div>
    </div>
    <div style='text-align:center;padding-top:20px;'>
      
      <button onclick='mySwipe.prev()'>prev</button> 
      <button onclick='mySwipe.next()'>next</button>
    
    </div>
    <script src="jquery-1.9.1.min.js" type="text/javascript"></script>
    <script src='swipe.js'></script>
    <script>
    
    // pure JS
    var elem = document.getElementById('mySwipe');
    window.mySwipe = Swipe(elem, {
      startSlide: 0,
      auto: 3000,
      // continuous: true,
      disableScroll: true,
      // stopPropagation: true,
      callback: function(index, element) {
        console.log(index);
      },
      // transitionEnd: function(index, element) {}
    });
    
    // with jQuery
    // window.mySwipe = $('#mySwipe').Swipe().data('Swipe');
    
    </script>
  • 相关阅读:
    多测师讲解html _伪类选择器17_高级讲师肖sir
    多测师讲解html _后代选择器16_高级讲师肖sir
    多测师讲解html _组合选择器_高级讲师肖sir
    多测师讲解html _标签选择器14_高级讲师肖sir
    前端 HTML form表单标签 input标签 type属性 重置按钮 reset
    前端 HTML form表单标签 textarea标签 多行文本
    前端 HTML form表单标签 input标签 type属性 file 上传文件
    前端 HTML form表单标签 input标签 type属性 radio 单选框
    前端 HTML form表单标签 input标签 type属性 checkbox 多选框
    前端 HTML form表单目录
  • 原文地址:https://www.cnblogs.com/lihaozhou/p/3644972.html
Copyright © 2011-2022 走看看