每次项目使用轮播的时候都是直接用swiper,实话实说,功能强大,简单。但是想想自己每次都使用最基本的,于是就自己捣鼓了一个。
先说一下无缝滚动原理吧:
原本是在想有没有什么好办法可以不复制节点,后来写了一些动画发现没办法做到,于是也是采用了复制前后节点的方法。如上图,在第一个复制一个最后一个的节点,最后一个加上第一个的节点。当滚动到最后一个的时候,继续往下滚动到复制的节点,然后在下一次滚动之前判断,如果是最后一个立马无动画滚动到初始化位置。向右的时候也是一样的原理。
这边也说一下动画问题,本来使用定时器去移动,后来有个网友推荐使用的是transition,确实很美丽,样式只要有改变都会是缓慢的,然后移动使用的是绝对定位position,然后使用transform的translate3d,移动的是一整个块,而不是单个的元素。
移动的距离本来使用的是元素style.left,后面发现多次点击会有很大误差,于是采用index去计算元素的宽度然后移动。附上动画方法:
moveAnimate(el){
let startX = -this.currentIndex * el.offsetWidth;
let endX = startX - el.offsetWidth;
el.style.transform = `translate3d(${endX}px, 0px, 0px)`;
el.style.transition = `${this.wSwiperOptions.speed}s`;
},
需要注意一下,为了无缝滚动,在无感知恢复原来位置的时候,需要设置transition的时间为0:
judgeCurrent(el){
if(this.currentIndex == el.children.length - 2){
this.currentIndex = 0;
el.style.transform = `translate3d(-${el.offsetWidth}px, 0px, 0px)`;
el.style.transition = '0s';
}else if(this.currentIndex == -1){
this.currentIndex = el.children.length - 3;
el.style.transform = `translate3d(-${el.offsetWidth * (this.currentIndex + 1)}px, 0px, 0px)`;
el.style.transition = '0s';
};
}
如果是元素最后一个(已经复制了节点),就初始化到整体向左移动一格的位置,无感知无动画。如果是第一个,初始化到倒数第二个,这边会有-1的场景是左右点击按钮,右边按钮点一下index是减1的。
自动轮播方法:
autoPlay(el){
if(!this.wSwiperOptions.autoPlay){
return
}
this.intervalId = setInterval(() => {
this.judgeCurrent(el);
this.currentIndex++;
this.moveAnimate(el);
this.pagingParallelism(el);
}, this.wSwiperOptions.time);
}
预留一个参数是否要自动轮播,每次轮播后index需要加1,然后执行动画,并且分页圆点要跟随。
很多方法操作会先清除定时器,然后再重新轮播,否则会有冲突,因为定时器还未执行的时候清除就不会执行。
分页圆点也需要一些判断:
pagingParallelism(el){
let len = el.children.length;
if(this.currentIndex == -1 || this.currentIndex == len - 3){
this.pageIndex = len - 3;
}else if(this.currentIndex == len - 2){
this.pageIndex = 0;
}else{
this.pageIndex = this.currentIndex;
}
}
pageIndex 是控制选中状态用的。
必须得说一下左右按钮,没有默认箭头,为了可以让别人自己定义(其实是懒得弄一套icon到项目里)。然后采用的是监听绑定的方法。
最简单的左右箭头,分页圆点和轮播有了,最后加上了几个移动端touch的几个小点,和鼠标hover的功能。比较遗憾的是还没写移动端touch过程轮播随着移动距离移动。代码很简单,可以自行扩展。
其实说再多还是不如自己下载下来看一下代码,还是希望可以下载下来看看代码,使用一下,以后简单的轮播组件就用自己的,当然,兼容性是比不上那些第三方组件库的,但是自己的随心所欲的可扩展。
已经发布npm,不得不说一下,一开始发布版本号没改,发不上去,改了之后不知道是不是因为之前没改报错的原因,一直报错400,花了很多时间查找为什么,后来改了版本号再发布就好了,地址:
https://www.npmjs.com/package/wade-ui
或者直接下载:npm install wade-ui
(完)