js에서 슬라이딩 플러그인을 구현하는 방법

王林
풀어 주다: 2020-03-23 09:41:21
앞으로
2195명이 탐색했습니다.

js에서 슬라이딩 플러그인을 구현하는 방법

기본 아이디어는 기본 초기 구성 매개변수를 사용하여 Slider 클래스를 캡슐화하는 것입니다.

Slider.prototype(프로토타입 체인에 있음)에는 제스처를 모니터링하여 슬라이딩 효과를 구현하는 방법이 있습니다.

Swiper.js를 사용하면 더 복잡한 슬라이딩 효과를 얻을 수 있습니다.

(추천 튜토리얼: javascript 튜토리얼)

코드는 다음과 같습니다:

/* 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);
}
로그인 후 복사

더 멋진 자바스크립트 특수 효과 코드는 다음에서 볼 수 있습니다: javascript 특수 효과

위 내용은 js에서 슬라이딩 플러그인을 구현하는 방법의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

관련 라벨:
js
원천:jb51.net
본 웹사이트의 성명
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.
인기 튜토리얼
더>
최신 다운로드
더>
웹 효과
웹사이트 소스 코드
웹사이트 자료
프론트엔드 템플릿
회사 소개 부인 성명 Sitemap
PHP 중국어 웹사이트:공공복지 온라인 PHP 교육,PHP 학습자의 빠른 성장을 도와주세요!