從前只作過PC端輪播組件,實現方式也是margin負值和setTimeout。前一陣看到一個比較精簡的移動端輪播組件的實現https://github.com/ximan/swipeSlide/blob/gh-pages/js/swipeSlide.js,用translate代替margin負值,而且添加了對touch事件的處理。在這裏總結一下這個組件的實現。git
全部的li絕對定位於容器左上角,寬度100%,高度100%。github
1.組件init步驟:ide
1)若是設定了連續輪播,則複製first slide到最後一幀後,last slide到第一幀前。函數
2)計算輪播距離(幻燈片寬度或高度。下面都假設是寬度)width.spa
3)爲每個li設置transition屬性(好像沒用)指針
4)第0個li向左translate width, 第1個li不移動,第2個li向右translate width, 依次類推。這樣全部的幻燈片從層疊到排列。事件
5)調用antoSlide()開始輪播ip
2. autoSlide的實現:get
1)中止autoSlide定時器it
2)setInterval設置每speed ms執行一次fnSlide('next'),播放下一slide, 每次播放300ms. 定時器指針賦值給autoSlide.
3. fnSlide實現。
組件有一個全局_index. 每次播放根據_index的值。
1)若是播放下一slide(next), _index++
若是播放上一slide, _index--
若是固定某個slide, _index = _slide
也可能以上狀況都不是,那就是默認播放完當前_index對應的slide. 這種狀況是針對當前slide由於觸摸事件中止播放然後又恢復播放的狀況,下文將描述。
2)若是是循環播放:
若是當前已到最後一幅幻燈片且仍需播放下一幻燈片,則正常播放下一幅幻燈片,執行fnScroll(300),而後設置_index = 0;300ms之後執行fnScroll(0)將ul瞬間移動到第一幅幻燈片。 //播放的是位於最後的第一幅幻燈片,300ms的時間是自定義。
若是當前已到第一幅幻燈片且仍需播放上一幅幻燈片,則正常播放上一幅幻燈片,執行fnScroll(300), 而後設置_index = length - 1; 300ms之後執行fnScroll(0)將ul瞬間移動到最後一幅幻燈片。//播放的是位於最前面的最後一幅幻燈片,300ms可自定義。
若是以上兩種狀況都不是,則執行fnScroll(300)正常滾動。
3)若是不是循環播放:
若是當前已到最後一幅且向後,設置index = 0, 若是是第一幅且向前,設置index = length - 1; 而後執行fnScroll(300);這樣的效果是在300ms內幻燈片從第一幅快進到最後一幅或者從最後一幅迅速回退到第一幅,其實不是太好看。
3. fnScroll函數的實現
1)根據參數設置ul的transition時間爲0或300ms等等
2)ul根據_index的值translate. 對於每一幅幻燈片,ul translate的距離是固定的,與translate開始時ul的位置無關。因此在觸摸回調中,fnScroll可能只是移動了半幅幻燈片。
4. 對觸摸事件的處理
1)touchstart:
isScrolling=undefined.
moveDistance = 0
記錄startX與startY
2)touchmove:
暫停autoSlide;
計算已移動的距離moveDistance;
若是是首次移動,則根據x移動距離與y移動距離的大小判斷是滾動仍是滑動。若是是滾動則不做處理,若是是滑動,設置ul transition的時間爲0
若是不是循環播放,已經到最後一幅幻燈片還要向後或者已到第一幅幻燈片還要向前,設置moveDistance = 0;
ul translate moveDistanc距離
3)touchend:
若是當前是滾動,則恢復autoSlide.
若是滑動距離小於50px,視做播放當前幻燈片,fnScroll('')
若是滑動距離大於50px,視做播放下一幅或上一幅幻燈片,fnScroll('next')或者fnScroll('prev');
恢復autoSlide.