Heim  >  Artikel  >  Web-Frontend  >  So implementieren Sie ein Sliding-Plug-In in js

So implementieren Sie ein Sliding-Plug-In in js

王林
王林nach vorne
2020-03-19 13:30:292226Durchsuche

So implementieren Sie ein Sliding-Plug-In in js

Die Grundidee besteht darin, eine Slider-Klasse mit standardmäßigen anfänglichen Konfigurationsparametern zu kapseln.

Slider.prototype (in der Prototypenkette) verfügt über eine Methode zum Implementieren des Gleitens. Durch die Überwachung von Gesten wird der Gleiteffekt erreicht.

Komplexere Gleiteffekte können mit Swiper.js erzielt werden.

(Empfohlenes Tutorial: Javascript-Tutorial)

Der Code lautet wie folgt:

/* 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);
}

Weitere coole Javascript-Spezialeffektcodes finden Sie unter: Javascript-Spezialeffekte

Das obige ist der detaillierte Inhalt vonSo implementieren Sie ein Sliding-Plug-In in js. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Stellungnahme:
Dieser Artikel ist reproduziert unter:jb51.net. Bei Verstößen wenden Sie sich bitte an admin@php.cn löschen