当前位置: 移动技术网 > IT编程>开发语言>JavaScript > JS实现滑动插件

JS实现滑动插件

2020年03月09日  | 移动技术网IT编程  | 我要评论

本文实例为大家分享了js实现滑动插件的具体代码,供大家参考,具体内容如下

基本思路是封装一个slider类, 拥有默认初始配置参数。
slider.prototype(原型链上)拥有实现滑动的方法,通过监听手势,实现滑动的效果。
比较复杂的滑动效果, 可以使用swiper.js 来实现。

/* 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 === '') return style
  return vendor + style.charat(0).touppercase() + style.substr(1)
}

var transform = prefix('transform'),
  transition = prefix('transition')

var slider = function(options) {
  // 初始化配置参数
  this.options = $.extend({
    slidewrap: '.pages',  // 容器
    slideitem: '.page', // 滑动单元的元素
    direction: 'y', // 滑动的方向
    effect: 'slide',  // 滑动的效果
    triggledist: 100,  // 触发滑动的手指移动最小位移
    followfinger: true, // 是否跟随手指移动
    duration: .4,  // 翻页的延时
    currentidx: 0  // 初始显示的页码
  }, options)

  var effectdict = {
    'slide' : ['slide', 'slide'],
    'scale' : ['slide', 'scale']
  }

  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 = 'ontouchend' 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 == 'y' ? height : width)

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

  _bindevents: function() {
    var _this = this,
      pageswrap = this.pageswrap

    var events = this._supporttouch ? 'touchstart touchmove touchend touchcancel' : 'mousedown mousemove mouseup mousecancel'

    events.split(' ').foreach(function(e) {
      pageswrap.addeventlistener(e, _this)
    })

    window.addeventlistener('orientationchange', this)
    window.addeventlistener('resize', this)
  },

  handleevent: function(e) {
    switch (e.type) {
      case 'orientationchange':
      case 'resize':
        this._init()
        break
      case 'touchstart':
      case 'mousedown':
        this._start(e)
        break
      case 'touchmove':
      case 'mousemove':
        this._move(e)
        break
      case 'touchend':
      case 'touchcancel':
      case 'mouseup':
      case 'mousecancel':
        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 == 'x' ? 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('webkittransitionend', function() {
      $current.classlist.remove('current')
      $target.classlist.add('current')
      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) ? 'all 0.4s' : ''
    el.style[transform] = 'translate3d(' + ('y' == this.options.direction ? '0, ' + val + 'px' : (val + 'px, 0')) + ',0)'
  },

  scale: function(el, val) {
    el.style.webkittransition = 'all 0.4s'
    el.style[transform] = 'scale(' + (1 - math.round(math.abs(val) / this._distance / 4*100) / 100) + ') translatez(0)'
  }
}

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

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持移动技术网。

如对本文有疑问, 点击进行留言回复!!

相关文章:

验证码:
移动技术网