一、 思路:使用定时器完成图片的位置的偏移,使用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) } }
复制