一、輪播的實現原理是怎樣的?如果讓你來實現,你會抽象出哪些函數(or接口)供使用?(比如 play())
輪播的常見實現有兩種:
- 橫向排列所有圖片,父元素設置為絕對定位,通過設置
left
或者right
來位移父元素達到圖片切換效果(需要注意,該父元素的父元素寬度應為一張圖片大小,并overflow: hidden
)。 - 所有圖片絕對定位,這樣實際上所有圖片都重合在一個位置,然后控制對應圖片顯示,其他圖片隱藏。
一般輪播的功能有:
- 左右位移按鈕
- 中間的指定下標移動按鈕
- 自動輪播
因此我會未以上三個功能抽出來做邏輯運算,然后再加個move()
函數,在每個功能里邊調用。另外還有一些動畫回調或其他小功能抽出做單獨函數。如:
/**
* 新建一個輪播對象,所有方法基于 jQuery
* @param {Object} options
* {
* swiperNode: 輪播的父節點 jQ 對象(即將位移的對象) ( 必填 )
* btnsNode: 輪播的按鈕對象數組 jQ 對象 ( 必填 )
* speed: 輪播速度,單位 ms 。默認 500
* distance: 每張圖片的寬度,也就是每次位移的最小距離,單位 px 。默認 960 px
* currentIndex: 當前輪播圖位置
* activeClass: 激活的樣式,默認 active
* auto: 是否開啟自動輪播, Boolean 類型, 默認 false
* interval: 自動輪播間隔,單位 ms ,默認 2000 。
* }
*/
function _swiper(options) {
this.swiperNode = options.swiperNode
this.btnsNode = options.btnsNode
this.speed = options.speed || 500
this.distance = options.distance || 960
this.currentIndex = options.currentIndex || 0
this.activeClass = options.activeClass || 'active'
this.auto = options.auto || false
this.interval = options.interval || 2000
this.start = 0
this.end = Math.floor((this.swiperNode).innerWidth() / this.distance) - 1
}
/**
* 初始化,激活輪播
*/
_swiper.prototype.init = function () {
this.currentMode(this.currentIndex)
this._judgeAuto()
}
/**
* 計算模式,用于左右位移
* @param {Number} offset { -1 / 1 => 控制輪播位移方向}
*/
_swiper.prototype.calculateMode = function (offset) {
this._optimizedAutoMode()
this.currentIndex += offset
if (this.currentIndex < 0) {
this.swiperNode.css('left', -this.distance * this.end + 'px')
this.currentIndex = this.end - 1
} else if (this.currentIndex > this.end) {
this.swiperNode.css('left', this.start + 'px')
this.currentIndex = this.start + 1
}
this._move()
this._judgeAuto()
}
/**
* 按鈕模式,根據按鈕的索引位移圖片
* @param {Number} index {按鈕的索引}
*/
_swiper.prototype.currentMode = function (index) {
this._optimizedAutoMode()
this.currentIndex = index
this._move()
this._judgeAuto()
}
/**
* 判斷自動模式是否開啟
*/
_swiper.prototype._judgeAuto = function () {
if (this.auto) {
this._autoMode()
}
}
/**
* 自動模式函數,定時器模擬點擊
*/
_swiper.prototype._autoMode = function () {
var self = this
clearInterval(self.timer)
self.timer = setInterval(function () {
self.calculateMode(1)
}, self.interval)
}
/**
* 優化自動模式體驗,手動時先清除自動模式
*/
_swiper.prototype._optimizedAutoMode = function () {
clearInterval(this.timer)
}
/**
* 輪播對象的移動函數
*/
_swiper.prototype._move = function () {
this.swiperNode.stop().animate({
left: -this.distance * this.currentIndex + 'px'
}, this.speed, this._animateCallBack.call(this))
}
/**
* 輪播動畫的回調函數,用于同步按鈕顯示
*/
_swiper.prototype._animateCallBack = function () {
var fakeIndex = this.currentIndex
var len = this.btnsNode.length
if (fakeIndex >= len) {
fakeIndex = 0
}
this.btnsNode.removeClass(this.activeClass)
$(this.btnsNode[fakeIndex]).addClass(this.activeClass)
}