图片轮播是一个很常见的功能,html结构大体如下:
<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
是可以省略的。
这种做法很容易实现,然而有个问题:首尾元素更迭时,整个UL列表会快速滚动一遍。体验不太好。
在看过手淘的banner后,发现它的过渡效果很平滑,类似“无限”轮播的效果。经研究,它是通过3D动画平移和绝对定位实现的。在此基础上,我做了点优化,支持动态切换轮播顺序。
此时,必须要css进行辅助了:
.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代码如下:
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变量。
至此,大功告成。
来源:oschina
链接:https://my.oschina.net/u/2324376/blog/736894