您的位置:首页 > Web前端 > JavaScript

JS实现滑动插件

2020-01-15 18:08 2943 查看

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

以上就是本文的全部内容,希望对大家的学习有所帮助

您可能感兴趣的文章:

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  js 滑动插件