微信号:w3ctrain

介绍:w3ctrain官方公众号,定期推送前端资讯.

轮播无缝循环思路

2016-04-25 18:08 Helkyle

轮播插件是前端开发中必不可少的组件,很多页面都会用到它。常用的轮播插件有 swiperslickslidesjsBootstrap Carousel等等。

这些轮播插件通常都有一个设置是否可循环的属性 loop。

实现思路通常有两种。

思路一

第一种是只显示当前元素和下一元素,其他子元素都隐藏不见。
以Bootstrap Carousel为例,


<div class="carousel-inner" role="listbox">
 <div class="item active">
   1
 </div>
 <div class="item">
   2
 </div>
 <div class="item">
   3
 </div>
</div>



/* 默认情况下 .item 元素隐藏*/
.carousel-inner>.item {
   position: relative;
   display: none;
   transition: transform .6s ease-in-out;
}


/* 活动状态的元素才显示 */
.carousel-inner>.active, .carousel-inner>.next, .carousel-inner>.prev {
   display: block;
}


/* 切换状态,显示目标元素 */
.carousel-inner>.item.active, .carousel-inner>.item.next.left, .carousel-inner>.item.prev.right {
   left: 0;
   transform: translate3d(0,0,0);
}


/* 切换过程,前后两个元素的过度 */
.carousel-inner>.item.active.left, .carousel-inner>.item.prev {
   left: 0;
   transform: translate3d(-100%,0,0);
}

.carousel-inner>.item.active.right, .carousel-inner>.item.next {
   left: 0;
   transform: translate3d(100%,0,0);
}


效果图如下:


实现一效果图


说明:
初始效果,除了 active 元素,其他元素都不显示。
切换过程,下一个元素显示出来,前后两个元素执行过度动画。
切换结束,显示 active 元素,隐藏其他元素。

思路二

除了将子元素拆分,还有一种思想思路是将整体进行迁移。
所有子元素都在同一行内,通过移动整体来。

已 swiper 为例:


<div class="swiper-container swiper-container-horizontal">
   <div class="swiper-wrapper" style="transform: translate3d(-1110px, 0px, 0px); transition-duration: 0ms;">
     <div class="swiper-slide swiper-slide-duplicate swiper-slide-prev" data-swiper-slide-index="9" style="width: 1080px; margin-right: 30px;">3</div>

     <div class="swiper-slide swiper-slide-active" data-swiper-slide-index="0" style="width: 1080px; margin-right: 30px;">1</div>
     <div class="swiper-slide swiper-slide-next" data-swiper-slide-index="1" style="width: 1080px; margin-right: 30px;">2</div>
     <div class="swiper-slide" data-swiper-slide-index="2" style="width: 1080px; margin-right: 30px;">3</div>

     <div class="swiper-slide swiper-slide-duplicate" data-swiper-slide-index="0" style="width: 1080px; margin-right: 30px;">1</div>
 </div>
</div>


html为最终呈现出来的代码
为了能够让用户觉得是无缝衔接,使用了障眼法,在第一个子元素前边添加最后一个元素,在最后一个子元素后面添加第一个元素。

效果图如下:

思路二向左滑动效果图


修复循环过渡只是中间的状态,瞬间完成,用户感知不到。


s.fixLoop = function () {
   var newIndex;
   //Fix For Negative Oversliding
   if (s.activeIndex < s.loopedSlides) {
       newIndex = s.slides.length - s.loopedSlides * 3 + s.activeIndex;
       newIndex = newIndex + s.loopedSlides;
       s.slideTo(newIndex, 0, false, true);
   }
   //Fix For Positive Oversliding
   else if ((s.params.slidesPerView === 'auto' && s.activeIndex >= s.loopedSlides * 2) || (s.activeIndex > s.slides.length - s.params.slidesPerView * 2)) {
       newIndex = -s.slides.length + s.activeIndex + s.loopedSlides;
       newIndex = newIndex + s.loopedSlides;
       s.slideTo(newIndex, 0, false, true);
   }
};


swiper 中用来修复循环的代码。在循环模式下,每次进入上一页,下一页 swiper 都会执行 fixLoop 方法,判断是否溢出,回到用户真正看到的位置。

补充

以上内容动画的实现均是使用 CSS3,如果你使用 js 来实现动画,那么你可能会用到模运算(%),注意在 JavaScript 中,mod 运算的结果可能跟你想象的不太一样。例如我们理解中 mod 4 的结果会有0,1,2,3。而在 JavaScript 中 -5 % 4 的结果为 -1,而其他语言可能运算结果为 3。这跟底层的实现有关。
如果你需要拿到0,1,2,3,这样的结果,可以使用


var modNum = ( ( num % max ) + max ) % max


欢迎加入前端Q群( 467969149 )

 
w3ctrain 更多文章 IT圈装逼速成指南 使用data URIs 综合指南:何时使用 Em 与 Rem 12个鲜为人知的CSS技能(上) 使用JavaScript修改伪类样式的方法总结
猜您喜欢 10个你应该学习使用的PHP特性 谷歌的野心:用Android统治全世界 案例 | Web 服务器偶尔无法打开,坑坑坑 我看全栈工程师 惊艳全球数据行业的16个数据可视化例子(投票译文)