做爲一個專業的前端(笑),圖片輪播插件應該是一個很容易實現的功能插件css
隨着境界的提升,咱們編寫插件愈來愈注重它的效率。因而,鑑於工做的關係,我仿照了一下淘寶的插件設計,寫了一款我我的比較滿意的圖片輪播插件(淘寶的插件有bug!)html
事先聲明,這個插件是基於angular的directive的(換成其餘編寫形式同理)前端
特色:node
translateX + transition 製做動畫(css3處理動畫的速度比較高)css3
事件代理算法
字符串形式生成DOM動畫
streamModule.directive('picscroll', function() { return { restrict: 'E', scope: { list: "=", space: '@' }, template: [ '<div class="picscroll-con">', ' <div class="outer-con">', ' <div class="inner-con">', // ' <div class="page" ng-repeat="url in list"><img src="{{url}}"></div>', ' </div>', ' </div>', ' <ul class="points">', // ' <li ng-class="{\'curLi\': cuIndex == $index}" ng-repeat="url in list"></li>', ' </ul>', '</div>' ].join(''), link: function(scope, elem, attr) { var contain = elem.find('.inner-con'); var points = elem.find('.points'); var width = 0; var space = Number(scope.space) || 500; var tmpl = { page: '<div class="page"><img src="{url}"></div>', point: '<li index="{index}"></li>', }; // 初始化監聽器 contain.css('transition', 'transform ' + space / 1000.0 + 's ease'); contain.css('position', 'relative'); points.bind('click', function(event) { var tar = event.target || {}; if(tar.nodeName.toUpperCase() != 'LI') return ; jump(tar.getAttribute('index')); }); // 初始化功能(刷新界面什麼的調用一下這個方法便可) init(); function init() { var html1 = tmpl.page.replace('{url}', scope.list[scope.list.length - 1]); var html2 = ''; width = elem.find('.outer-con').width(); for (var i = 0; i < scope.list.length; i++) { html1 += tmpl.page.replace('{url}', scope.list[i]); html2 += tmpl.point.replace('{index}', i); }; html1 += tmpl.page.replace('{url}', scope.list[0]); contain.html(html1); points.html(html2); jump(0); } // 初始化頁面運動 var curIndex = 0; var movebase = 0; function jump(index) { index = Number(index); movebase = movebase || 0; // 錨點 var children = points.children(); var len = children.length; children.eq(curIndex).removeClass('curLi'); children.eq(index).addClass('curLi'); // 頁面輪動 if (index == len - 1 && curIndex == 0) { // 第一張到最後一張 contain.css('transform', 'translateX(' + -movebase + 'px)'); setTimeout(function() { movebase = -width * len + movebase; contain.css('left', movebase + 'px'); }, space); } else if (index == 0 && curIndex == len - 1) { // 最後一張到第一張 contain.css('transform', 'translateX(' + (-width * (len + 1) - movebase) + 'px)'); setTimeout(function() { movebase = width * len + movebase; contain.css('left', movebase + 'px'); }, space); } else { contain.css('transform', 'translateX(' + (-width * (index + 1) - movebase) + 'px)'); } // 結束 curIndex = index; } /********************** ********************** * 鑑於上面算法有點複雜,我稍稍的解釋一下吧 * transition控制translate的動畫,translate作移動(動畫),left作跳轉(瞬間) * 先後加上附加的最後,最前幀 * 當first->last或者last->first,先動畫到附加幀,動畫後left跳轉到真實的那幀上 * 更新基準線movebase * movebase的更新規律就是 * 向前(後)滾len個幀,加上基準 ********************* **********************/ } }; });
其實代碼功能尚未實現完,譬如:自動輪播等~之後補上url