本文实例为大家分享了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);
}
/* 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);
}以上就是本文的全部内容,希望对大家的学习有所帮助。