简体   繁体   English

如何在 Javascript 中创建无限轮播?

[英]How to create infinite carousel in Javascript?

I want to make an infinite carousel in javascript.我想在 javascript 中制作一个无限轮播。 When the elements go off-screen, I clone them and paste them at the end of the list.当元素 go 离开屏幕时,我克隆它们并将它们粘贴到列表的末尾。 But after a minute there are a lot of cloned elements in the HTML layout.但是一分钟后,HTML 布局中有很多克隆元素。 I decided to delete this element after cloning.我决定在克隆后删除这个元素。 But I get an instant offset of all elements.但我得到了所有元素的即时偏移。 How to avoid it?如何避免? Or maybe there is another algorithm on how to implement this endless carousel?或者也许还有另一种算法来实现这个无尽的轮播?

Here's the code https://codepen.io/alessandro-kex/pen/abGWNEK这是代码https://codepen.io/alessandro-kex/pen/abGWNEK

 window.addEventListener("load", function () { const slideContainer = document.querySelector(".carousel"); const slidesWrapper = document.querySelector(".carousel-slides"); let slides = document.querySelectorAll(".carousel-slide"); let index = 0; const interval = 1500; let moveDistance = 0; const paddingRight = 50; let lastSlideIndex = slides.length - 1; let firstClone; const startSlide = (index) => { this.setInterval(() => { moveDistance = moveDistance + slides[index].clientWidth + paddingRight; slidesWrapper.style.transform = `translateX(${-moveDistance}px)`; slidesWrapper.style.transition = "1s"; firstClone = slides[index].cloneNode(true); firstClone.id = `first-clone-${index}`; slidesWrapper.append(firstClone); /*If uncomment it - then the problem starts */ //slides[index].remove(); index++; }, interval); }; startSlide(index); });
 * { margin: 0; padding: 0; box-sizing: border-box; }.carousel { margin: 0 auto; width: 100%; position: relative; }.carousel-slides { display: flex; list-style: none; gap: 50px; flex-shrink: 1; }.carousel-slide { position: relative; min-width: 0; flex-shrink: 0; }.carousel-slide { height: 100px; display: flex; align-items: center; justify-content: center; min-width: 0; }.carousel-item-text { white-space: nowrap; }.carousel-item-img { width: 100px; height: auto; }.round { padding: 30px 50px; border-radius: 120px; }.light-blue { background-color: #d8f1ff; }.pink { background-color: #ffeaf0; }.purpule { background-color: #eae9ff; }
 <div class="carousel"> <ul class="carousel-slides"> <li class="carousel-slide" data-number="0"> <img src="https://via.placeholder.com/150" alt="" class="carousel-item-img"> </li> <li class="carousel-slide light-blue round" data-number="1"> <span class="carousel-item-text">11111111 1111 <br> 111111111</span> </li> <li class="carousel-slide"> <img src="https://via.placeholder.com/150" alt="" class="carousel-item-img"> </li> <li class="carousel-slide pink round"> <span class="carousel-item-text">22222 22222 <br> 222222222 2222222222 222222222</span> </li> <li class="carousel-slide"> <img src="https://via.placeholder.com/150" alt="" class="carousel-item-img"> </li> <li class="carousel-slide light-blue round"> <span class="carousel-item-text">333 333333333 <br> 333333333333</span> </li> <li class="carousel-slide"> <img src="https://via.placeholder.com/150" alt="" class="carousel-item-img"> </li> <li class="carousel-slide purpule round"> <span class="carousel-item-text">4444 444444444444<br> 44444</span> </li> <li class="carousel-slide"> <img src="https://via.placeholder.com/150" alt="" class="carousel-item-img"> </li> <li class="carousel-slide pink round"> <span class="carousel-item-text">55555555 55555<br> 55 5555</span> </li> <li class="carousel-slide"> <img src="https://via.placeholder.com/150" alt="" class="carousel-item-img"> </li> <li class="carousel-slide pink round"> <span class="carousel-item-text">6666666 6666666666 <br> 66666 6666666 66666</span> </li> <li class="carousel-slide"> <img src="https://via.placeholder.com/150" alt="" class="carousel-item-img"> </li> <li class="carousel-slide light-blue round"> <span class="carousel-item-text">777777 777 777<br> 77 77777</span> </li> <li class="carousel-slide"> <img src="https://via.placeholder.com/150" alt="" class="carousel-item-img"> </li> <li class="carousel-slide purpule round" data-number="16"> <span class="carousel-item-text">888 8888<br> 88888888</span> </li> </ul> </div>

You should rather create one carousel and keep all the data in an array with JavaScript.您应该创建一个轮播并将所有数据保存在一个带有 JavaScript 的数组中。 Then by default, on load, display the first element on the array.然后默认情况下,在加载时,显示数组上的第一个元素。 When the user clicks to view next item on carousel or the time for a certain slide expires, simply call a function to change the slide.当用户点击查看轮播上的下一项或某个幻灯片的时间到期时,只需调用 function 即可更改幻灯片。 For this, initialize a counter to keep track of slide index viewing at the moment and update it whenever the slide is changed.为此,初始化一个counter以跟踪当前的幻灯片索引查看情况,并在幻灯片更改时更新它。 When the user wishes to view the next slide while they are on the last slide, set the counter to 0 .当用户希望在最后一张幻灯片上查看下一张幻灯片时,将counter设置为0 Similarly, when the user wishes to view previous slide when they are on the first slide, set the counter to n-1 where n is the number of slides that you offer.同样,当用户希望在第一张幻灯片上查看上一张幻灯片时,请将counter设置为n-1 ,其中n是您提供的幻灯片数。

For this kind of thing you should familiarize yourself with promises对于这种事情,你应该熟悉Promise

otherwise the idea is the right one,否则这个想法是正确的,
1 - make a translateX with a transition time 1 - 制作带有过渡时间的 translateX
2 - once the transition is finished remove the transition time 2 - 转换完成后删除转换时间
3 - put the first element at the end and reset the translateX to zero 3 - 将第一个元素放在末尾并将 translateX 重置为零
4 - start again... 4 - 重新开始...

complete code:完整代码:

 (async ()=> // async IIFE code for slider. { const interval = 1500 // ms, paddingRight = 50, slideContainer = document.querySelector('.carousel'), slidesWrapper = document.querySelector('.carousel-slides'), slides = document.querySelectorAll('.carousel-slides > li'), delay = ms => new Promise(r => setTimeout(r, ms)), movLeft = (el, mov) => new Promise(r => { el.ontransitionend =_=> { el.ontransitionend = null el.style.transition = 'none'; r() } el.style.transition = '1s'; el.style.transform = `translateX(${-mov}px)`; }); let index = 0; while (true) // infinite carrousel loop { await delay( interval ) await movLeft( slidesWrapper, slides[index].clientWidth + paddingRight ) slidesWrapper.appendChild( slides[index] ) // mov first slide to the end slidesWrapper.style.transform = `translateX(0)` // rest translateX index = ++index % slides.length } })()
 * { margin: 0; padding: 0; box-sizing: border-box; }.carousel { margin: 0 auto; width: 100%; position: relative; }.carousel-slides { display: flex; list-style: none; gap: 50px; flex-shrink: 1; }.carousel-slide { position: relative; min-width: 0; flex-shrink: 0; height: 100px; display: flex; align-items: center; justify-content: center; min-width: 0; }.carousel-item-text { white-space: nowrap; }.carousel-item-img { width: 100px; height: auto; }.round { padding: 30px 50px; border-radius: 120px; }.light-blue { background-color: #d8f1ff; }.pink { background-color: #ffeaf0; }.purpule { background-color: #eae9ff; }
 <div class="carousel"> <ul class="carousel-slides"> <li class="carousel-slide" data-number="0"> <img src="https://via.placeholder.com/150" alt="" class="carousel-item-img"> </li> <li class="carousel-slide light-blue round" data-number="1"> <span class="carousel-item-text">11111111 1111 <br> 111111111</span> </li> <li class="carousel-slide"> <img src="https://via.placeholder.com/150" alt="" class="carousel-item-img"> </li> <li class="carousel-slide pink round"> <span class="carousel-item-text">22222 22222 <br> 222222222 2222222222 222222222</span> </li> <li class="carousel-slide"> <img src="https://via.placeholder.com/150" alt="" class="carousel-item-img"> </li> <li class="carousel-slide light-blue round"> <span class="carousel-item-text">333 333333333 <br> 333333333333</span> </li> <li class="carousel-slide"> <img src="https://via.placeholder.com/150" alt="" class="carousel-item-img"> </li> <li class="carousel-slide purpule round"> <span class="carousel-item-text">4444 444444444444<br> 44444</span> </li> <li class="carousel-slide"> <img src="https://via.placeholder.com/150" alt="" class="carousel-item-img"> </li> <li class="carousel-slide pink round"> <span class="carousel-item-text">55555555 55555<br> 55 5555</span> </li> <li class="carousel-slide"> <img src="https://via.placeholder.com/150" alt="" class="carousel-item-img"> </li> <li class="carousel-slide pink round"> <span class="carousel-item-text">6666666 6666666666 <br> 66666 6666666 66666</span> </li> <li class="carousel-slide"> <img src="https://via.placeholder.com/150" alt="" class="carousel-item-img"> </li> <li class="carousel-slide light-blue round"> <span class="carousel-item-text">777777 777 777<br> 77 77777</span> </li> <li class="carousel-slide"> <img src="https://via.placeholder.com/150" alt="" class="carousel-item-img"> </li> <li class="carousel-slide purpule round" data-number="16"> <span class="carousel-item-text">888 8888<br> 88888888</span> </li> </ul> </div>

My idea is with pure CSS.我的想法是纯 CSS。 There are two containers red and blue and they overlap each-other.有红色和蓝色两个容器,它们相互重叠。 Here is my draft:这是我的草稿: 图片

I have used a=700px which is the width of the containers, and w=500px which is the width of the green wrapper.我使用a=700px是容器的宽度,而w=500px是绿色包装器的宽度。 Hope this would help somebody:)希望这会对某人有所帮助:)

 .wrapper { width: 500px; overflow-x: hidden; border: 2px solid black; position: relative; height: 100px; }.first { width:700px; height: 100px; background-color: red; position: absolute; left:0px; top:0; animation: firstDiv 10s linear infinite; } @keyframes firstDiv { 0 {left: 0px;} 15% {left: -200px;} 50% {left: -700px;} 65.9% {left: -900px;} 66% {left: 500px;} 99.9% {left: 0px;} 100% {left: 0px;} }.second { width:700px; height: 100px; background-color: blue; position: absolute; left:700px; top:0; animation: secondDiv 10s linear infinite; } @keyframes secondDiv { 0 {left: 700px;} 15% {left: 500px;} 50% {left: 0px;} 65.9% {left: -200px;} 66% {left: -200px;} 99.9% {left: -700px;} 100% {left: 700px;} }
 <div class="wrapper"> <div class="first">first container first container first container first container first container first container first container first container</div> <div class="second">second container second container second container second container second container second container second container</div> </div>

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM