Home > Web Front-end > JS Tutorial > body text

How to implement sliding plug-in in js

王林
Release: 2020-03-23 09:41:21
forward
2193 people have browsed it

How to implement sliding plug-in in js

The basic idea is to encapsulate a Slider class with default initial configuration parameters.

Slider.prototype (on the prototype chain) has a method to implement sliding. By monitoring gestures, the sliding effect is achieved.

More complex sliding effects can be achieved using Swiper.js.

(Recommended tutorial: javascript tutorial)

The code is as follows:

/* PollyFill for iOS 5.* */
if (!Function.prototype.bind) {
  Function.prototype.bind = function (oThis) {
    var args = Array.prototype.slice.call(arguments, 1)
    var f2bind = this
    var fnop = function () {}
    var bound = function () {
      return f2bind.apply(this instanceof fnop && oThis
        ? this
        : oThis,
        args.concat(Array.prototype.slice.call(arguments)))
    }
    fnop.prototype = this.prototype
    bound.prototype = new fnop()
    return bound
  }
}

// 添加浏览器前缀
function prefix(style) {
  var vendor = (function() {
    var transArr = ['transform', 'webkitTransform', 'MozTransform', 'msTranform', 'OTransform'],
      vendors = ['', 'webkit', 'Moz', 'ms', 'O'],
      elementStyle = document.createElement('div').style

    for (var i = 0; i < vendors.length; i++) {
      if (transArr[i] in elementStyle) {
        return vendors[i]
      }
    }

    return false
  })()

  if (vendor === false) return false
  if (vendor === &#39;&#39;) return style
  return vendor + style.charAt(0).toUpperCase() + style.substr(1)
}

var TRANSFORM = prefix(&#39;transform&#39;),
  TRANSITION = prefix(&#39;transition&#39;)

var Slider = function(options) {
  // 初始化配置参数
  this.options = $.extend({
    slideWrap: &#39;.pages&#39;,  // 容器
    slideItem: &#39;.page&#39;, // 滑动单元的元素
    direction: &#39;Y&#39;, // 滑动的方向
    effect: &#39;slide&#39;,  // 滑动的效果
    triggleDist: 100,  // 触发滑动的手指移动最小位移
    followFinger: true, // 是否跟随手指移动
    duration: .4,  // 翻页的延时
    currentIdx: 0  // 初始显示的页码
  }, options)

  var EffectDict = {
    &#39;slide&#39; : [&#39;slide&#39;, &#39;slide&#39;],
    &#39;scale&#39; : [&#39;slide&#39;, &#39;scale&#39;]
  }

  this.pagesWrap = document.querySelector(this.options.slideWrap)
  this.pages = document.querySelectorAll(this.options.slideItem)

  this.hook = this.options.slideController
  this._total = this.pages.length
  this._pageX = 0
  this._pageY = 0
  this._distance = 0 // 页面之间切换的距离
  this._moveDist = 0 // touch 滑动的距离
  this._supportTouch = &#39;ontouchend&#39; in window
  this._touching = false

  this._enter = this[EffectDict[this.options.effect][0]].bind(this)
  this._leave = this[EffectDict[this.options.effect][1]].bind(this)

  this._init()
  this._bindEvents()
}
Slider.prototype = {
  _init: function() {
    var width = this.pagesWrap.clientWidth,
      height = this.pagesWrap.clientHeight,
      currentIdx = this.options.currentIdx,
      pages = this.pages,
      total = this._total,
      distance = this._distance = (this.options.direction == &#39;Y&#39; ? height : width)

    // 初始化各个 page 的位置
    for (var i = 0; i < this._total; i++) {
      if (i == currentIdx) {
        pages[i].classList.add(&#39;current&#39;)
      } else {
        this._enter(pages[i], i < currentIdx ? -distance : distance, 2)
      }
    }
  },

  _bindEvents: function() {
    var _this = this,
      pagesWrap = this.pagesWrap

    var events = this._supportTouch ? &#39;touchstart touchmove touchend touchcancel&#39; : &#39;mousedown mousemove mouseup mousecancel&#39;

    events.split(&#39; &#39;).forEach(function(e) {
      pagesWrap.addEventListener(e, _this)
    })

    window.addEventListener(&#39;orientationchange&#39;, this)
    window.addEventListener(&#39;resize&#39;, this)
  },

  handleEvent: function(e) {
    switch (e.type) {
      case &#39;orientationchange&#39;:
      case &#39;resize&#39;:
        this._init()
        break
      case &#39;touchstart&#39;:
      case &#39;mousedown&#39;:
        this._start(e)
        break
      case &#39;touchmove&#39;:
      case &#39;mousemove&#39;:
        this._move(e)
        break
      case &#39;touchend&#39;:
      case &#39;touchcancel&#39;:
      case &#39;mouseup&#39;:
      case &#39;mousecancel&#39;:
        this._end(e)
        break
    }
  },

  _start: function(e) {
    if (this._touching) {
      e.preventDefault()
      e.stopPropagation()
      return
    }

    this._touching = true
    this._moveDist = 0

    var touches = (this._supportTouch ? e.touches[0] : e),
      distance = this._distance,
      enter = this._enter

    var $current = this.pages[this.options.currentIdx],
      $next = $current.nextElementSibling,
      $prev = $current.previousElementSibling

    this._pageX = touches.pageX
    this._pageY = touches.pageY

    $current.style.zIndex = 1

    if ($next) {
      $next.style.zIndex = 2
      enter($next, distance)
    }

    if ($prev) {
      $prev.style.zIndex = 2
      enter($prev, -distance)
    }
  },

  _move: function(e) {
    e.preventDefault()

    if (!this._touching) return

    var touches = (this._supportTouch ? e.touches[0] : e),
      direction = this.options.direction,
      distance = this._distance

    var currentIdx = this.options.currentIdx,
      $current = this.pages[this.options.currentIdx],
      $next = $current.nextElementSibling,
      $prev = $current.previousElementSibling,
      xDist = touches.pageX - this._pageX,
      yDist = touches.pageY - this._pageY,
      enter = this._enter,
      leave = this._leave,
      moveDist = this._moveDist = (direction == &#39;X&#39; ? xDist : yDist)

    if (this.options.followFinger) {
      $next && enter($next, moveDist + distance)
      $prev && enter($prev, moveDist - distance)

      // 因为不能翻页,所以制造拖动困难的效果
      if ((currentIdx == 0 && moveDist > 0) || (currentIdx == this._total && moveDist < 0)) {
        return this.slide($current, moveDist / 4)
      }

      leave($current, moveDist)
    }
  },

  _end: function(e) {
    var move = this._moveDist,
      distance = this._distance,
      triggleDist = this.options.triggleDist,
      enter = this._enter,
      $current = this.pages[this.options.currentIdx],
      $next = $current.nextElementSibling,
      $prev = $current.previousElementSibling

    this._touching = false

    this._enter($current, 0)
    $next && enter($next, distance)
    $prev && enter($prev, -distance)

    if ($next && move < -triggleDist && this.hook.shouldGoToNext($current)) return this._next()
    if ($prev && move > triggleDist && this.hook.shouldGoToPrev($current)) return this._prev()
  },

  _next: function() {
    this.go2page(this.options.currentIdx + 1)
  },

  _prev: function() {
    this.go2page(this.options.currentIdx - 1)
  },

  go2page: function(idx) {

    var $current = this.pages[this.options.currentIdx],
      $target = this.pages[idx],
      enter = this._enter,
      leave = this._leave,
      distance = (idx < this.options.currentIdx ? this._distance : -this._distance)

    $($target).one(&#39;webkitTransitionEnd&#39;, function() {
      $current.classList.remove(&#39;current&#39;)
      $target.classList.add(&#39;current&#39;)
      this.hook.didGoToPage($target, $current)
    }.bind(this))

    leave($current, distance)
    enter($target, 0)

    this._moveDist = 0
    this.options.currentIdx = idx
  },


  /**
   * 切页的效果
   * 目前只支持两种效果:
   * 1. Slide(普通的滑动)
   * 2. Scale(缩放滑动)
   */
  slide: function(el, val, need) {
    need = need || 1
    el.style.webkitTransition = (need == 1) ? &#39;all 0.4s&#39; : &#39;&#39;
    el.style[TRANSFORM] = &#39;translate3d(&#39; + (&#39;Y&#39; == this.options.direction ? &#39;0, &#39; + val + &#39;px&#39; : (val + &#39;px, 0&#39;)) + &#39;,0)&#39;
  },

  scale: function(el, val) {
    el.style.webkitTransition = &#39;all 0.4s&#39;
    el.style[TRANSFORM] = &#39;scale(&#39; + (1 - Math.round(Math.abs(val) / this._distance / 4*100) / 100) + &#39;) translateZ(0)&#39;
  }
}

var slideController = {
  shouldGoToPrev: function(el) {
    return false;
  },
  shouldGoToNext: function(el) {
    return false;;
  },
  didGoToPage: function(el, prevEl) {
    return false;
  }
}


function query(selector){
  return document.querySelector(selector);
}
Copy after login

More cool javascript special effects codes are available at: javascript Special effects

The above is the detailed content of How to implement sliding plug-in in js. For more information, please follow other related articles on the PHP Chinese website!

Related labels:
js
source:jb51.net
Statement of this Website
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn
Popular Tutorials
More>
Latest Downloads
More>
Web Effects
Website Source Code
Website Materials
Front End Template
About us Disclaimer Sitemap
php.cn:Public welfare online PHP training,Help PHP learners grow quickly!