如何在HTML+CSS+JS图片滑块中实现反向切换动画?
图片滑块反向切换动画修复方案
问题说明
当前实现的图片滑块已支持导航箭头、指示圆点、自动播放,点击元素会重置计时器,正向循环切换正常。但点击「prev」按钮或当前圆点之前的任意圆点时,无法触发反向切换动画,需要实现该场景下滑块从左到右的切换效果。
修复思路
核心是根据切换方向区分动画逻辑:
- 正向切换(next/当前圆点之后的圆点):保持原有「旧滑块左滑隐藏,新滑块右滑显示」的动画
- 反向切换(prev/当前圆点之前的圆点):新增「旧滑块右滑隐藏,新滑块左滑显示」的动画
修改后的完整代码
JavaScript 代码
var slider = document.getElementsByClassName("slider")[0]; var sliderDots = Array.prototype.slice.call(document.getElementsByClassName("dots")[0].children); var sliderContents = Array.prototype.slice.call(document.getElementsByClassName("elements")[0].children); var sliderArrowLeft = document.getElementsByClassName("arrow-left")[0]; var sliderArrowRight = document.getElementsByClassName("arrow-right")[0]; var sliderSpeed = 4000, currentSlide = 0, currentActive = 0, sliderTimer = 0; // 新增direction参数,判断切换方向:forward/backward function playSlide(slide, direction = 'forward') { // 清空所有元素的状态类 for (var k = 0; k < sliderDots.length; k++) { sliderContents[k].classList.remove("active", "inactive", "active-reverse", "inactive-reverse"); sliderDots[k].classList.remove("active"); } // 处理循环边界 if (slide < 0) { slide = currentSlide = sliderContents.length - 1; } if (slide > sliderContents.length - 1) { slide = currentSlide = 0; } if (currentActive != currentSlide) { // 根据方向给旧滑块添加隐藏类 if (direction === 'forward') { sliderContents[currentActive].classList.add("inactive"); } else { sliderContents[currentActive].classList.add("inactive-reverse"); } } // 根据方向给新滑块添加显示类 if (direction === 'forward') { sliderContents[slide].classList.add("active"); } else { sliderContents[slide].classList.add("active-reverse"); } sliderDots[slide].classList.add("active"); currentActive = currentSlide; // 重置计时器 clearTimeout(sliderTimer); sliderTimer = setTimeout(function() { playSlide(currentSlide += 1); }, sliderSpeed) } // 左箭头点击:反向切换 sliderArrowLeft.addEventListener("click", function() { playSlide(currentSlide -= 1, 'backward'); }) // 右箭头点击:正向切换 sliderArrowRight.addEventListener("click", function() { playSlide(currentSlide += 1); }) // 圆点点击:判断点击的圆点是在当前之前还是之后,确定方向 for (var l = 0; l < sliderDots.length; l++) { sliderDots[l].addEventListener("click", function() { var targetIndex = sliderDots.indexOf(this); var direction = targetIndex < currentSlide ? 'backward' : 'forward'; playSlide(currentSlide = targetIndex, direction); }) } playSlide(currentSlide);
CSS 代码
.slider { overflow: hidden; position: relative; } .contents { width: 100%; height: 200px; position: relative; overflow: hidden; } .arrow-left, .arrow-right { width: 50px; height: 50px; bottom: 0; cursor: pointer; display: block; text-align: center; line-height: 50px; background: rgb(200,200,200); position: absolute; z-index: 2; } .arrow-left { left: 0; } .arrow-right { right: 0; } .dots { height: 14px; bottom: 0; left: 50%; font-size: 0; text-align: right; position: absolute; z-index: 2; transform: translateX(-50%); } .dot { width: 12px; height: 12px; margin-left: 5px; margin-right: 5px; display: inline-block; cursor: pointer; border-style: solid; border-width: 1px; border-color: rgb(100, 100, 100); } .dot.active { background: rgb(200, 200, 200); } .elements { width: 100%; overflow: hidden; transform: translate(0px); } .image { width: 100%; height: 100px; top: 0; position: absolute; opacity: 0; } .image span { width: 100%; height: 100px; text-align: center; line-height: 100px; display: block; background: rgb(200, 200, 200); } /* 正向切换类 */ .image.active { position: relative; z-index: 1; opacity: 1; } .image.inactive { z-index: -3; opacity: 1; } .image.active span { animation: show .5s ease-in-out forwards; } .image.inactive span { animation: hide .5s ease-in-out forwards; } /* 反向切换类 */ .image.active-reverse { position: relative; z-index: 1; opacity: 1; } .image.inactive-reverse { z-index: -3; opacity: 1; } .image.active-reverse span { animation: show-reverse .5s ease-in-out forwards; } .image.inactive-reverse span { animation: hide-reverse .5s ease-in-out forwards; } /* 正向动画关键帧 */ @keyframes show { 0% { transform: translateX(+100%); } 100% { transform: translateX(0); } } @keyframes hide { 0% { opacity: 1; transform: translateX(0); } 100% { opacity: 0; transform: translateX(-100%); } } /* 反向动画关键帧 */ @keyframes show-reverse { 0% { transform: translateX(-100%); } 100% { transform: translateX(0); } } @keyframes hide-reverse { 0% { opacity: 1; transform: translateX(0); } 100% { opacity: 0; transform: translateX(+100%); } }
HTML 代码
<div class="slider"> <div class="contents"> <div class="arrow-left">prev</div> <div class="arrow-right">next</div> <div class="dots"> <li class="dot"></li> <li class="dot"></li> <li class="dot"></li> </div> <div class="elements"> <div class="image"><span>image 1</span></div> <div class="image"><span>image 2</span></div> <div class="image"><span>image 3</span></div> </div> </div> </div>
关键修改点
- JS中给
playSlide函数新增direction参数,判断切换是正向还是反向 - 圆点点击时,对比目标索引和当前索引,自动判断切换方向
- CSS中新增反向切换的类和对应的关键帧动画,实现旧滑块右滑隐藏、新滑块左滑显示的效果
内容的提问来源于stack exchange,提问作者tez
相关产品推荐
相关产品推荐

