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