从前只作过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.