html组件:
<div class="carousel-wrap" needCarousel needAutoCarousel >
<!--
自定义属性:
needCarousel:是否需要无缝轮播
needAutoCarousel:是否需要自动轮播
-->
<div class="points-wrap"></div>
</div>
JS轮播组件:
function(arr){
//参数arr代表需要轮播图片的数组
var carousel = document.querySelector(".carousel-wrap");
var pointsArr = arr;
//是否需要无缝滑屏
var needCarousel = carousel.getAttribute("needCarousel");
needCarousel=needCarousel!=null?true:false;
//如果需要无缝轮播则需要拷贝图片数组
if(needCarousel){
arr = arr.concat(arr);
}
if(carousel){
//轮播图片列表布局
var ulNode = document.createElement("ul");
var styleNode = document.createElement("style");
ulNode.classList.add("list");
for(var i = 0 ;i<arr.length;i++){
ulNode.innerHTML+='<li><a href=""><img src="'+arr[i]+'" alt="" /></a></li>'
}
styleNode.innerHTML=".carousel-wrap>.list{width: "+arr.length*100+"%;}.carousel-wrap>.list li{width: "+(1/arr.length*100)+"%;}"
carousel.appendChild(ulNode);
document.head.appendChild(styleNode);
var imgNode = document.querySelector(".carousel-wrap>.list a>img");
//需要延迟一段时间好让浏览器先渲染完DOM结构
setInterval(function(){
carousel.style.height = imgNode.offsetHeight+"px";
},100);
var pointsWrap = document.querySelector(".carousel-wrap > .points-wrap");
if(pointsWrap){
for(var i = 0 ;i<pointsArr.length;i++){
if(i==0){
pointsWrap.innerHTML+="<span class='active'></span>";
}else{
pointsWrap.innerHTML+="<span></span>";
}
}
var pointsSpan = document.querySelectorAll(".carousel-wrap > .points-wrap > span");
}
/*
滑屏
1,拿到元素一开始位置
2,拿到手指一开始的位置
3,拿到手指move的实时位置
4,将手指移动的距离加给元素
*/
var index=0;
//X轴上:手指、元素一开始的位置
var startX=0;
var elementX=0;
//Y轴上:手指、元素一开始的位置
var startY=0;
var elementY=0;
//是否是X轴滑屏,主要用来防控抖动
var isX=true;
//是否是第一次滑动
var isFrist=true;
carousel.addEventListener("touchstart",function(ev){
ev = ev || event;
var TouchC = ev.changedTouches[0];
ulNode.style.transition="none";
/*
无缝滑屏
1,点击第一组的第一张时,瞬间跳到第二组的第一张
2,点击最后一组的最后一张时,瞬间跳到第一组的最后一张
*/
if(needCarousel){
//获取轮播图片的索引
var index = tai.transformCss(ulNode,"translateX")/document.documentElement.clientWidth;
if(index==0){
//如果是第一张图片,那么则跳转到第二组图片的第一张
index = -pointsArr.length;
}else if(-index==arr.length-1){
//如果是最后一张图片,那么则跳转到第一组图片的最后一张
index = 1-pointsArr.length;
}
//设置移动位置
tai.transformCss(ulNode,"translateX",index*document.documentElement.clientWidth);
}
startX = TouchC.clientX;
elementX = tai.transformCss(ulNode,"translateX");
startY = TouchC.clientY;
elementY = tai.transformCss(ulNode,"translateY");
clearInterval(carouselTimer);
isX=true;
isFrist=true;
});
carousel.addEventListener("touchmove",function(ev){
//判断"第一次之后"的滑动效果
if(!isX){
return;
}
ev = ev || event;
var TouchC = ev.changedTouches[0];
var moveX = TouchC.clientX;
var disX = moveX - startX;
var moveY = TouchC.clientY;
var disY = moveY-startY;
/*
* 防抖动:
* 如果手指一开始在X轴上滑动,那么之后无论怎么滑,都会抖动
* 如果手指一开始在Y轴上滑动,那么之后无论怎么滑,都不会抖动
*
* */
//判断第一次滑动的方向,并确定是否禁掉之后滑动效果
if(isFrist){
isFrist=false;
//判断用户滑动的方向,如果y>x,那么代表第一次滑动的是y轴
if(Math.abs(disY)>Math.abs(disX)){
isX=false;
return ;
}
}
//设置滑屏位置:滑屏位置应该=上次滑屏位置+当前移动的位置
tai.transformCss(ulNode,"translateX",elementX + disX);
});
carousel.addEventListener("touchend",function(ev){
ev = ev || event;
//获取当前图片索引
index = tai.transformCss(ulNode,"translateX")/document.documentElement.clientWidth;
index = Math.round(index);
//如果第一张向右滑动,那么索引为第一张图片
if(index > 0){
index=0;
//如果最后一张向左滑动,那么索引为最后一张图片
}else if(index<1-arr.length){
index=1-arr.length;
}
pointActive(index)
ulNode.style.transition = ".5s transform";
translateX = index*document.documentElement.clientWidth;
tai.transformCss(ulNode,"translateX",translateX);
//手动滑屏之后,判断是否开启了自动滑屏
if(needAutoCarousel){
autoCarousel();
}
});
//自动轮播
var carouselTimer=0;
var needAutoCarousel = carousel.getAttribute("needAutoCarousel");
needAutoCarousel = needAutoCarousel!=null?true:false;
if(needAutoCarousel){
autoCarousel();
}
function autoCarousel(){
clearInterval(carouselTimer);
carouselTimer = setInterval(function(){
//自动轮播时,如果轮播到最后一张时,那么将回到第一组的最后一张,并设置起过渡效果为none
if(index==1-arr.length){
index=1-arr.length/2;
ulNode.style.transition="none";
tai.transformCss(ulNode,"translateX",index*document.documentElement.clientWidth);
}
setTimeout(function(){
index--;
pointActive(index);
ulNode.style.transition=".5s transform";
tai.transformCss(ulNode,"translateX",index*document.documentElement.clientWidth);
},50);
},2000);
}
//圆点样式
function pointActive(index){
if(!pointsWrap){
return;
}
for(var i=0;i<pointsSpan.length;i++){
pointsSpan[i].classList.remove("active");
}
pointsSpan[-index%pointsArr.length].classList.add("active");
}
}
}
注:其中tai.transformCss(v1,v2,v3)函数请参考https://blog.csdn.net/qq_35165469/article/details/91050052链接