一、 思路:使用定时器完成图片的位置的偏移,使用transition完成图片的过渡动画。
上图解释: 单个黄色矩形表示图片,包裹所有矩形的外层这里叫“盒子”,蓝色盖住的部分代表可视盒子。
1.自动轮播
效果图:
实现思路:
上图黄色方块代表轮播图的排列位置,默认图片从start开始,切换到end的时候再往后走一个图片的宽度,到达chang的位置。此时通过js把盒子的transition过渡属性的时间置为0s,然后让盒子的位置切换到start的位置(此时看不到过度动画),再通过js把盒子的过渡属性置为n秒(n为滚动时间),继续自动切换,此为一个循环。
2.左点击无缝切换
效果图:
实现思路:
当点击“左”按钮时,将盒子的偏移量减去一张图片的距离,盒子则向左偏移,当盒子的位置到达change位置的时候,清除定时器,把盒子的transition置为0s,把盒子的位置切换到start(因为change和start的图片是一样的,并且没有动画,所以看来就是没有切换), 然后设置等待n秒后继续自动滚动。此为一个完整的循环。
3.右点击无缝切换
效果图:
实现思路:
当点击“右”按钮时,将盒子的偏移量加一张图片的宽度,盒子则向右偏移,当盒子位置到达start前一张图片的位置时,清除定时器,把盒子的过渡的时间置为0s, 把盒子的位置设置到end的位置, 然后设置等待n秒继续自动滚动,此为一个循环。
二、代码实现
1.HTML代码
<body>
<div class="outer">
<!-- 切换按钮 -->
<span class="left">左</span>
<span class="right">右</span>
<ul class="inner">
<li>5</li>
<li>1</li>
<li>2</li>
<li>3</li>
<li>4</li>
<li>5</li>
<li>1</li>
</ul>
<!-- 小圆点 -->
<div class="ctrlCircle">
<span class="on" index="1"></span>
<span index="2"></span>
<span index="3"></span>
<span index="4"></span>
<span index="5"></span>
</div>
</div>
</body>
2.CSS代码
<style>
*{
margin: 0;
padding: 0;
}
.outer{
position: relative;
margin: 100px auto;
width: 400px;
height: 150px;
overflow: hidden;
}
.on{
background-color: #bfa!important;
}
.inner{
position: relative;
/* 此处输入一张图片宽度的负值(起始位置)*/
left: -400px;
/* 总宽度 = 图片个数 * 一张图片宽度 */
width: 2800px;
height: 150px;
}
li{
font-size: 50px;
text-align: center;
list-style: none;
/* 图片盒子宽度 */
width: 400px;
height: 100px;
height: 100%;
line-height: 150px;
float: left;
}
.ctrlCircle{
position: absolute;
bottom: 10px;
left: 160px;
}
.ctrlCircle span{
cursor: pointer;
border-radius: 50%;
margin-right: 5px;
display: inline-block;
width: 10px;
height: 10px;
background-color: red;
}
.left{
cursor: pointer;
z-index: 2;
position: absolute;
top: 71px;
left: 10px;
}
.right{
cursor: pointer;
z-index: 2;
position: absolute;
top: 71px;
right: 10px;
}
.inner li:nth-child(1){
background-color: pink;
}
.inner li:nth-child(2){
background-color: yellow;
}
.inner li:nth-child(3){
background-color: skyblue;
}
.inner li:nth-child(4){
background-color: green;
}
.inner li:nth-child(5){
background-color: yellow;
}
.inner li:nth-child(6){
background-color: pink;
}
.inner li:nth-child(7){
background-color: yellow;
}
</style>
3.JS代码
//包裹图片的盒子
const inner = document.querySelector(".inner")
//左边切换按钮
const left = document.querySelector(".left")
//右边切换按钮
const right = document.querySelector(".right")
//所有圆点
const ctrlCircle = document.querySelectorAll(".ctrlCircle span")
//原点的盒子(用来添加点击事件)
const circleContaniner = document.querySelector(".ctrlCircle")
//图片宽度
var imgWidth = 400
//此处输入一张图片的负值代表滚动到的位置
var initLeft = -imgWidth
//图片总数量
var sumImg = 5
//滚动一张图片的间隔
var steptTime = 2000
//自动滚动定时器
var Scrolltimer
//初始过渡动画
inner.style.transition = "1s"
//当前小圆点
var thisCircle = 0
//操作后重新启动定时器的时间
var clickAfterTime = 3000
//滚动函数
var autoScroll = () => {
for (let i = 0; i < ctrlCircle.length; i++) {
ctrlCircle[i].className = "null"
}
thisCircle = -(initLeft / imgWidth)
// if ()
if (thisCircle >= 5) thisCircle = 4
ctrlCircle[thisCircle].className = "on"
initLeft -= imgWidth
if (initLeft < (sumImg) * -imgWidth) {
//迅速切换到第一张图片并把动画置为0s
initLeft = 0
inner.style.transition = "0s"
//此定时器用来控制切换完图片后重新加上过度动画
var animaAgain = setTimeout(() => {
inner.style.transition = "1s"
Scrolltimer = setInterval(autoScroll, steptTime)
}, 50)
clearInterval(Scrolltimer)
}
inner.style.left = initLeft + "px"
}
Scrolltimer = setInterval(autoScroll, steptTime)
//左切换
left.onclick = (e) => {
clearInterval(Scrolltimer)
for (let i = 0; i < ctrlCircle.length; i++) {
ctrlCircle[i].className = "null"
}
//底下圆点跟随
thisCircle = -(initLeft / imgWidth)
if (thisCircle >= 5) thisCircle = 0
ctrlCircle[thisCircle].className = "on"
if (initLeft < (sumImg) * -imgWidth) {
initLeft = 0
inner.style.transition = "0s"
} else {
inner.style.transition = "1s"
}
initLeft = ((initLeft / imgWidth) - 1) * imgWidth
console.log(initLeft);
inner.style.left = initLeft + "px"
// 等待n秒重新启动自动滚动
var timerClickAfterScroll = setTimeout(() => {
clearInterval(Scrolltimer)
inner.style.transition = "1s"
Scrolltimer = setInterval(autoScroll, steptTime)
}, clickAfterTime)
}
//右切换
right.onclick = () => {
clearInterval(Scrolltimer)
initLeft = ((initLeft / imgWidth) + 1) * imgWidth
if (initLeft > 0) {
initLeft = -(imgWidth * (sumImg))
inner.style.transition = "0s"
} else {
inner.style.transition = "1s"
}
inner.style.left = initLeft + "px"
for (let i = 0; i < ctrlCircle.length; i++) {
ctrlCircle[i].className = "null"
}
//底下圆点跟随
thisCircle = -(initLeft / imgWidth) - 1
if (thisCircle >= 5) thisCircle = 0
if (thisCircle <= -1) thisCircle = 4
ctrlCircle[thisCircle].className = "on"
// 等待n秒重新启动自动滚动
var timerClickAfterScroll = setTimeout(() => {
clearInterval(Scrolltimer)
if (initLeft == -(sumImg + 1) * imgWidth) {
initLeft = 0
inner.style.transition = "1s"
}
Scrolltimer = setInterval(autoScroll, steptTime)
}, clickAfterTime)
}
circleContaniner.onclick = (e) => {
//事件冒泡判断是否点击的是原点按钮
if (e.target.tagName == "SPAN") {
//清除定时器
clearInterval(Scrolltimer)
//拿到点击的index并且切换图片
initLeft = e.target.getAttribute("index") * -imgWidth
inner.style.left = initLeft + "px"
for (let i = 0; i < ctrlCircle.length; i++) {
ctrlCircle[i].className = "null"
}
//底下圆点跟随
thisCircle = -(initLeft / imgWidth) - 1
if (thisCircle >= 5) thisCircle = 0
ctrlCircle[thisCircle].className = "on"
//n秒以后重新启动定时器
var timerClickAfterScroll = setTimeout(() => {
clearInterval(Scrolltimer)
Scrolltimer = setInterval(autoScroll, steptTime)
}, clickAfterTime)
}
}