21.JavaScript实现无缝轮播图
程序员文章站
2023-11-29 20:41:40
JavaScript实现无缝轮播图:
javascript实现无缝轮播图:
<!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> .container { position: relative; width: 500px; height: 400px; border: 1px solid #fff; margin: 20px auto; overflow: hidden; cursor: pointer; } .container .images img { display: block; float: left; } .container .dots { position: absolute; margin: 0 auto; left: 0; right: 0; bottom: 10px; background: rgba(255, 255, 255, .3); padding: 5px; border-radius: 20px; } .container .dots span { margin: 2px; width: 8px; height: 8px; display: block; border-radius: 50%; background: rgba(255, 255, 255, .5); float: left; } .container .dots span.active { background: #f40; } .container .arrow { display: none; } .container:hover .arrow { display: block; } .container .arrow .item { width: 40px; height: 40px; background: rgba(255, 255, 255, .5); color: #fff; position: absolute; top: 0; bottom: 0; margin: auto 0; text-align: center; line-height: 40px; font-size: 20px; } .container .arrow .leftarrow { left: 0; border-radius: 0 20px 20px 0; } .container .arrow .rightarrow { right: 0; border-radius: 20px 0 0 20px; } </style> </head> <body> <div class="container"> <div class="images"> </div> <div class="dots"> </div> <div class="arrow"> <div class="item leftarrow"><</div> <div class="item rightarrow">></div> </div> </div> <script> var config = { imgwidth: 500, //图片宽度 dotwidth: 12, //小圆点宽度 imagearray: ["./image/5.jpg", "./image/1.jpg", "./image/2.jpg", "./image/3.jpg", "./image/4.jpg", "./image/5.jpg", "./image/1.jpg" ], //存储图片路径的数组 doms: { images: document.queryselector(".images"), //存放图片的dom dots: document.queryselector(".dots"), //圆点的dom leftarrow: document.queryselector(".item.leftarrow"), //左一张的dom rightarrow: document.queryselector(".item.rightarrow") //右一张的dom }, currentindex: 2, //当前展示的图片下标 timer: { //计时器配置 id: null, //计时器id duration: 16, //每次切换图片,运动的间隔时间 totaltime: 1000 //每次切换图片,运动的时间总长 } }; initimages(); initdots(); //初始化图片元素 function initimages() { //创建图片元素 config.doms.images.style.width = config.imagearray.length * config.imgwidth + "px"; for (var i = 0; i < config.imagearray.length; i++) { var img = document.createelement("img"); img.src = config.imagearray[i]; config.doms.images.appendchild(img); } //展示第一张图片1.jpg config.doms.images.style.marginleft = -config.imgwidth * config.currentindex + "px"; } //创建圆点元素 function initdots() { config.doms.dots.style.width = (config.imagearray.length - 2) * config.dotwidth + "px"; for (var i = 0; i < config.imagearray.length - 2; i++) { var dot = document.createelement("span"); config.doms.dots.appendchild(dot); } config.doms.dots.children[config.currentindex - 1].classname = "active"; } //点击左箭头、右箭头、和圆点 config.doms.leftarrow.onclick = config.doms.rightarrow.onclick = config.doms.dots.onclick = function (e) { if (e.target.tagname === "div" && e.target.classlist.contains("leftarrow")) { //点击左箭头 var index = config.currentindex - 1;//向左跳转图片的下标 if(index === 0){// index = 5; } jumptoimage(index, "left"); } else if (e.target.tagname === "div" && e.target.classlist.contains("rightarrow")) { //点击右箭头 var index = config.currentindex + 1;//向右跳转图片的下标 if(index === 6){// index = 1; } jumptoimage(index, "right"); } else if (e.target.tagname === "span" && e.target.parentelement && e.target.parentelement.classlist .contains("dots")) { //点击小圆点 var index = array.from(config.doms.dots.children).indexof(e.target) + 1; jumptoimage(index, (index > config.currentindex) ? "right" : "left"); } } //跳转到哪张图片 function jumptoimage(index, direction) { //index:下一张图片的下标(1,25);direction方向(1.left:左;2.right:右); if (index === config.currentindex) { //若要跳转的图片下标和当前下标一样,不执行 return; } if (!direction) { //方向默认:为右 direction = "right"; } //要运动到的目标marginleft var newmarginleft = -index * config.imgwidth; //图片切换 //config.doms.images.style.marginleft = newmarginleft + "px"; autoplay(); //圆点也自动切换 for (var i = 0; i < config.doms.dots.children.length; i++) { config.doms.dots.children[i].classlist.remove("active"); } config.doms.dots.children[index - 1].classname = "active"; //切换完成后,改变当前图片下标 config.currentindex = index; //图片渐变动画,一点一点的改变marginleft function autoplay() { stopplay(); //在播放轮播图之前,把上次的动画先停掉 //当前的marginleft var currentmarginleft = parsefloat(window.getcomputedstyle(config.doms.images).marginleft); //图片总长度,不能算第一张和最后一张,这两张是额外增加重复的两张 var allimageslength = (config.imagearray.length - 2) * config.imgwidth; //1.计算运动总次数 var frequency = math.ceil(config.timer.totaltime / config.timer.duration); var currentnum = 0; //当前运动的次数 //2.计算运动的总距离 var alldistance = 0; if (direction == "left") { //向左运动 if (newmarginleft > currentmarginleft) { //目标marginleft > 当前marginleft //总距离 = 目标marginleft - 当前marginleft alldistance = newmarginleft - currentmarginleft; } else { //总距离 = 图片总长度 - |目标marginleft - 当前marginleft| alldistance = allimageslength - math.abs(newmarginleft - currentmarginleft); } } else { //向右运动 if (newmarginleft < currentmarginleft) { //目标marginleft < 当前marginleft //总距离 = 目标marginleft - 当前marginleft alldistance = newmarginleft - currentmarginleft; } else { //目标marginleft > 当前marginleft //总距离 = -(图片总长度 - |目标marginleft - 当前marginleft|) alldistance = -(allimageslength - math.abs(newmarginleft - currentmarginleft)); } } //3.计算每次运动改变的距离 var everydistance = alldistance / frequency; //每次运动距离 = 运动总距离 / 运动总次数 config.timer.id = setinterval(function () { //改变图片的marginleft currentmarginleft += everydistance; //若图片向右移动到额外的第一张(即数组中最后一张图片) if (direction === "right" && math.floor(math.abs(currentmarginleft)) > allimageslength) { currentmarginleft += allimageslength; //图片瞬间挪回第一张图片对应的位置 } else if (direction === "left" && math.ceil(math.abs(currentmarginleft)) < config .imgwidth) { //若图片向左移动到额外的最后一张(即数组中第一张图片) currentmarginleft -= allimageslength; //图片瞬间挪回最后一张图片对应的位置 } config.doms.images.style.marginleft = currentmarginleft + "px"; currentnum++; //每执行一次,当前运动次数++ if (currentnum === frequency) { //达到运动总次数,停止运动 stopplay(); } }, config.timer.duration); } //停止播放 function stopplay() { clearinterval(config.timer.id); config.timer.id = null; } } </script> </body> </html>
效果展示:
最后一张图片切换第一张图片的效果
图片数组存储一共七张图片,但是1.jpg 和 5.jpg存放了两次,用来衔接。这样从5.jpg切换到1.jpg的时候不会出现断档,五张图片的宽高是500 x 200
制作无缝轮播图的难点:
计算运动的总距离
向左运动,目标margin-left 和 当前的margin-left
目标marginleft > 当前marginleft //总距离 = 目标marginleft - 当前marginleft
目标marginleft < 当前marginleft //总距离 = 图片总长度 - |目标marginleft - 当前marginleft|
向右运动,目标margin-left 和 当前的margin-left
目标marginleft < 当前marginleft //总距离 = 目标marginleft - 当前marginleft
目标marginleft > 当前marginleft //总距离 = -(图片总长度 - |目标marginleft - 当前marginleft|)