图片轮播是一个很常见的功能,html结构大致以下:javascript
<div class="image-swiper"> <ul> <li><img src="xxx" alt="xxx" /></li> <li><img src="yyy" alt="yyy" /></li> 。。。。。。 </ul> </div>
一般的作法是,动态修改ul
元素的margin-left
值,实现从右往左轮播,反之亦然。此时div
是能够省略的。css
这种作法很容易实现,然而有个问题:首尾元素更迭时,整个UL列表会快速滚动一遍。体验不太好。html
在看过手淘的banner后,发现它的过渡效果很平滑,相似“无限”轮播的效果。经研究,它是经过3D动画平移和绝对定位实现的。在此基础上,我作了点优化,支持动态切换轮播顺序。java
此时,必需要css进行辅助了:web
.image-swiper { position: relative; overflow: hidden; width: 100%; height: 8em; ul { position: relative; white-space: nowrap; width: 100%; height: 100%; } li { position: absolute; top: 0; float: left; width: 100%; height: 100%; } img { display: block; vertical-align: middle; width: 100%; height: 100%; }
看到这里,能够发现,LI元素是层叠到一块儿的,因此才须要平移UL元素,再经过绝对定位子元素,达到换位的效果。JS代码以下:less
var w = $(window).width(); // 单独设定轮播图的大小 div.css('font-size', Math.round(w / 24) + 'px'); var count = images.length; // 单张图片无需轮播 if (count < 2) return; // 初始显示第一张图片 div.find('li').each(function(j, o){ o.style.left = j * w + 'px'; }); // 默认向左轮播 var i = 0, isLeft = true; var swipe = function() { if (isLeft) i++; else i--; // 确保列表在反复正反序切换过程当中,也能正确计算出下一个元素的下标值 var m = i >= 0 ? i % count : i % count === 0 ? 0 : count - Math.abs(i) % count; // 经过动画的方式切换图片 // 这里translate3d的实际做用同translateX,好处是会开启3D加速 div.children('ul').animate({ '-webkit-transform': 'translate3d(' + (-i*w) + 'px,0px,0px)', transform: 'translate3d(' + (-i*w) + 'px,0px,0px)' }); div.find('li').get(m).style.left = i*w+'px'; }; // 每隔三秒切换下一张图片 var timing = 3000; var iv = setInterval(swipe, timing); // 正反序切换的代码这里省略,归根结底是修改isLeft变量。
至此,大功告成。优化