本案例轮播的图片为4个
第四张 第一张 第二章 第三张 第四张 第一张
index从1开始,通过index来使得装图片的容器,left=-(index-1)*屏幕宽度+'px'
通过定时器开启轮播
1、自动循环轮播和无缝衔接:
(1)在四个图片前添四个图片的最后一张,四个图片的尾添加图片的第一张
使得轮播时,最后一张图片能自然切换到第一张
(2)无缝衔接(当原最后一张图片轮播到原首张时从首战开始轮播)
当原最后一张图片轮播到原首张时,关掉过渡动画,位移到原首张的距离
2、短距离回弹
判断拉动距离,如果距离小于给定值,不改变当前图片index
3、图片可拖动
通过touch事件,根据坐标进行
4、拖动结束播放
监听过渡态结束事件,在事件中开启轮播,注意清除之前的定时器
5、监听当索引(照片)处于最后一张(index=5)和出于第一张(index=0),关闭过渡态,直接位移到原图片对应位置
使用webkitTransitionEnd事件,当过渡态结束时触发,监听index变化
6、当处于过渡时不可拖动(节流阀)
在过渡态结束监听事件中设置旗帜=true,当处于过渡态时,设置旗帜=true
拖动事件和松开事件,只有当过渡态结束时才触发
代码示例:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
*{
margin:0;
padding: 0;
}
.con{
width:100%;
height: 300px;
overflow: hidden;
position: relative;
}
.banner{
width:100%;
height: 300px;
left: 0;
display: flex;
position: absolute;
}
.img{
width: 100%;
height: 100%;
}
.dot{
width: 100%;
position: absolute;
margin: 0 auto;
display: flex;
justify-content: center;
bottom: 20px;
}
.dot>div{
height: 10px;
width: 10px;
border-radius: 10px;
margin: 0 10px;
background-color: #ccc;
}
.dot>.on{
background-color: white;
}
</style>
</head>
<body>
<div class='con'>
<div class='banner'>
</div>
<div class='dot'>
<div></div>
<div></div>
<div></div>
<div></div>
</div>
</div>
<script>
var banner=document.querySelector('.banner');
var dots=document.querySelectorAll('.dot>div')
banner.style.left=-banner.offsetWidth+'px';
let timer;
let fx; //第一次触发x坐标
let mx; //移动过程x坐标
let ex; //结束过程x坐标
let left;
//索引从1开始,0为最后一张图片索引
let index=1;
//在过渡态结束才能手动滑动
let transition=true;
//制造图片
function getImg(url){
let index=url;
url='./imgs/'+url+'.jpg'
let img=document.createElement('img');
img.className='img';
img.src=url;
img.style.borderRadius='20px';
return img;
}
//图片只有4张
for(let i=1;i<5;i++)
{
banner.appendChild(getImg(i));
}
//给首前添加最后一张图片,尾后添加首张图片
banner.insertBefore(getImg(4),document.querySelector('.img:first-of-type'));
banner.appendChild(getImg(1));
//添加当前圆点样式
function now(index)
{
dots.forEach((item)=>{
item.className='';
})
dots[index].className='on';
}
now(0);
//自动轮播
var startTimer=function()
{
if(timer)
{
clearInterval(timer);
}
timer=setInterval(()=>{
//要移动4次才能到末尾添加的图片,然后返回到首张,即index=5
index++;
banner.style.transition='1s linear';
banner.style.left=-(index)*banner.offsetWidth+'px';
transition=false;
},2000)
}
startTimer();
//手动轮播
//记录第一次触摸位置
banner.ontouchstart=function(e)
{
//按下关闭轮播
clearInterval(timer);
let touch=e.touches[0];
fx=touch.clientX;
left=banner.style.left.substring(0,banner.style.left.length-2);
}
//记录移动过程距离
banner.ontouchmove=function(e)
{
if(transition)
{
let touch=event.touches[0];
mx=touch.clientX;
move=fx-mx;
//最终拖动位移
let res=left-move;
//取消拉动的过渡动画,否则会出现延迟响应
banner.style.transition='none';
banner.style.left=res+'px';
}
}
//记录最后一次位置,并根据第一次位置判断方向
banner.ontouchend=function(e)
{
if(transition)
{
transition=false;
let touch=e.changedTouches[0];
ex=touch.clientX;
let indicator=fx-ex;
//判断方向
//判断拉取距离,小于某个值,只是回弹,即index不变
if(Math.abs(indicator)>100)
{
//超过距离进行翻页
if(indicator<0) //上一张
{
index--;
}else{ //下一张
index++;
}
}
//翻页
banner.style.transition='1s linear';
banner.style.left=-(index)*banner.offsetWidth+'px';
}
}
//监听过渡态结束,每当到首尾最后一张时,滑动到对应位置衔接,以及对应圆点显示
banner.addEventListener('webkitTransitionEnd',()=>{
//如果到第一张index=0,就回到最后一张-1,即index=4
transition=true;
if(index==0)
{
index=4;
//清除过渡
banner.style.transition='none';
banner.style.left=-index*banner.offsetWidth+'px';
}
//如果到最后一张,即index=5,回到第一张,index=1
if(index==5)
{
index=1;
//清除过渡
banner.style.transition='none';
banner.style.left=-index*banner.offsetWidth+'px';
}
now(index-1);
startTimer();
})
</script>
</body>
</html>