JS实现滑动插件

 更新时间:2020年01月15日 08:35:09   作者:Zonebystar  
这篇文章主要为大家详细介绍了JS实现滑动插件,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下

本文实例为大家分享了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);
}

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

相关文章

  • 微信小程序 wx:for遍历循环使用实例解析

    微信小程序 wx:for遍历循环使用实例解析

    这篇文章主要介绍了微信小程序 wx:for遍历循环使用实例解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2019-09-09
  • js简单实现Select互换数据的方法

    js简单实现Select互换数据的方法

    这篇文章主要介绍了js简单实现Select互换数据的方法,涉及javascript动态操作select中option节点的相关技巧,具有一定参考借鉴价值,需要的朋友可以参考下
    2015-08-08
  • 简单实现JavaScript弹幕效果

    简单实现JavaScript弹幕效果

    这篇文章主要帮助大家简单实现JavaScript弹幕效果,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2017-05-05
  • Javascript变量函数声明提升深刻理解

    Javascript变量函数声明提升深刻理解

    本文主要介绍了Javascript变量函数声明提升深刻理解,Javascript变量函数声明提升Hoisting是在Javascript中执行上下文工作方式的一种认识,更多相关知识需要的小伙伴可以参考下面文章详细内容
    2022-06-06
  • JavaScript常用脚本汇总(一)

    JavaScript常用脚本汇总(一)

    这篇文章主要介绍了JavaScript常用脚本汇总系列的第一篇,给大家分享的是jquery限制文本框只能输入数字、封装DOMContentLoaded事件、用原生JS对AJAX做简单封装、跨域请求之JSONP、千分位格式化,有需要的小伙伴们参考下吧。
    2015-03-03
  • javascript实现电商放大镜效果

    javascript实现电商放大镜效果

    这篇文章主要为大家详细介绍了javascript实现电商放大镜效果,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2020-11-11
  • JavaScript如何把两个数组对象合并过程解析

    JavaScript如何把两个数组对象合并过程解析

    这篇文章主要介绍了JavaScript如何把两个数组对象合并过程解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2019-10-10
  • js获取元素在浏览器中的绝对位置

    js获取元素在浏览器中的绝对位置

    其原理就是利用HTMLElement.offsetParent属性,需要的朋友可以参考下。
    2010-07-07
  • js实现飞入星星特效代码

    js实现飞入星星特效代码

    这篇文章主要介绍了js实现飞入星星特效代码,主要通过控制背景与飞入点的样式,结合setTimeout函数即可实现星星飞入的效果,对于学习javascript有不错的参考借鉴价值,需要的朋友可以参考下
    2014-10-10
  • JS实现点击表头表格自动排序(含数字、字符串、日期)

    JS实现点击表头表格自动排序(含数字、字符串、日期)

    这篇文章主要介绍了利用JS如何实现点击表头后表格自动排序,其中包含数字排序、字符串排序以及日期格式的排序,文中给出了完整的示例代码,相信对大家具有一定的参考价值,感兴趣的朋友们一起来看看吧。
    2017-01-01

最新评论