圖片輪播是一個很常見的功能,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變量。
至此,大功告成。