作为一个专业的前端(笑),图片轮播插件应该是一个很容易实现的功能插件
随着境界的提高,我们编写插件越来越注重它的效率。于是,鉴于工作的关系,我仿照了一下淘宝的插件设计,写了一款我个人比较满意的图片轮播插件(淘宝的插件有bug!)
事先声明,这个插件是基于angular的directive的(换成其他编写形式同理)
特点:
- translateX + transition 制作动画(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个帧,加上基准 ********************* **********************/ } }; });
其实代码功能还没有实现完,譬如:自动轮播等~以后补上
时间: 2024-10-11 11:28:38