简体   繁体   English

使用javascript创建平滑的无限多项目轮播滑块

[英]creating smooth infinite multi item carousel slider using javascript

I am creating a slider with Javascript using cloning technique and translate.我正在使用克隆技术和翻译用 Javascript 创建一个滑块。 Below is the working example:-以下是工作示例:-

 var fragPre = document.createDocumentFragment(), fragPost = document.createDocumentFragment(), clonedPre, clonedPost, selectSlide = document.getElementById("numberOfSlides"), //options numberOfSlides = 3; var items = document.querySelectorAll("#gallery .slider-scroller-inner .item"), len = items.length, current = 1, /* the current item we're looking */ wrapper = document.getElementById("wrapper"), transformVal = 0; /* 1. Cloning last items and appending to first */ for(var i=numberOfSlides ; i > 0 ; i--) { clonedPre = items[items.length-i].cloneNode(true); fragPre.append(clonedPre); } wrapper.insertBefore(fragPre , items[0]); /* . Cloning first items and appending to first */ for(var j = 0 ; j <= numberOfSlides-1 ; j++) { clonedPost = items[j].cloneNode(true); fragPost.append(clonedPost); } wrapper.appendChild(fragPost); /* Slider arrow click function */ var slideWidth=items[0].offsetWidth; var counter = 0; var timer = null; var timeout = null; wrapper.style.transform = "translate3d(" + (-slideWidth) * (numberOfSlides) + "px,0,0)"; function arrowClick(dir) { clearTimeout(timeout); timeout = setTimeout(function() { counter = 0; direction = dir; var str = wrapper.style.transform; var left = str.substring(12, str.length - 11); console.log(left); animateSlide(current, left); }, 300); } /* slide number click function */ function changeCurrent(curr) { current = curr; wrapper.style.transform = "translate3d(" + -(slideWidth) * (current + (numberOfSlides-1)) + "px,0,0)"; } /* actual sliding effect */ function animateSlide(curr, left) { var timer = setInterval(function() { if(counter < slideWidth) { transformVal = parseInt(left, 10) + (-(++counter) * direction); wrapper.style.transform = "translate3d(" + transformVal + "px,0,0)"; } else { current += direction; cycle = !!(current === 0 || current > len); if (cycle) { current = (current === 0)? len : 1; wrapper.style.transform ="translate3d(" + (-(slideWidth) * (current + (numberOfSlides-1))) + "px,0,0)"; } counter = 0; clearInterval(timer); } }, 0); }
 body { margin: 0; padding: 0; } .carousel-slider-wrapper { width: 1200px; margin: 0 auto; position: relative; } .slider-scroller-wrap { overflow: hidden; } .slider-scroller { font-size: 0; white-space: nowrap; position: relative; top: 0; margin: 0; padding: 0; } .slider-scroller-inner { /* transition: .2s ease-out; */ } .slider-scroller-inner { display: flex; width: 100%; position: relative; } .slider-scroller-inner .item { display: inline-block; vertical-align: top; /* padding: 2px; */ box-sizing: border-box; /* border: 1px solid; */ cursor: grab; text-align: center; flex: 0 0 33.33%; } .slider-scroller-inner .item img { max-width: 100%; } button { font: 40px "Courier New"; border: none; box-shadow: 1px 2px 3px #666666; background: #e4e4e4; color: #626262; cursor: pointer; text-align: center; position: absolute; top: 50%; transform: translateY(-50%); height: 70px; z-index: 1; } button.prev { left: 0; } button.next { right: 0; } label, a { font: 14px Georgia; font-style: italic; color: #626262; } #indicators { padding: 0; margin: 1rem 0; overflow: hidden; text-align: center; } #indicators li { padding: .5rem; border-radius: 100%; font-weight: bold; background: #7592bd; display: inline-flex; height: 1.4rem; width: 1.4rem; color: #FFFFFF; text-align: center; cursor: pointer; justify-content: center; align-items: center; margin-right: .3rem; } #indicators li:hover { box-shadow: 1px 2px 3px #333333; }
 <div class="carousel-slider-wrapper"> <button class="prev" type="button" id="prev" onclick="arrowClick(-1)">&lsaquo;</button> <div class="slider-scroller-wrap"> <div class="slider-scroller" id="gallery"> <!-- mask --> <div class="slider-scroller-inner" id="wrapper"> <div class="item"><img src="https://newyse-res.cloudinary.com/image/upload///t_mcms_larger/f_auto/v1511188164/33-2426430.jpg"></div> <div class="item"><img src="https://newyse-res.cloudinary.com/image/upload///t_mcms_larger/f_auto/v1511186177/33-2425761.jpg"></div> <div class="item"><img src="https://newyse-res.cloudinary.com/image/upload///t_mcms_larger/f_auto/v1511186164/33-2425751.jpg"></div> <div class="item"><img src="https://newyse-res.cloudinary.com/image/upload///t_mcms_larger/f_auto/v1511185761/33-2425646.jpg"></div> <div class="item"><img src="https://newyse-res.cloudinary.com/image/upload///t_mcms_larger/f_auto/v1557227665/33-2893456.jpg"></div> <div class="item"><img src="https://newyse-res.cloudinary.com/image/upload///t_mcms_larger/f_auto/v1511970254/33-2437550.jpg"></div> </div> </div> </div> <button class="next" type="button" id="next" onclick="arrowClick(1)">&rsaquo;</button> </div> <ul id="indicators" class=""> <li onclick="changeCurrent(1)">1</li> <li onclick="changeCurrent(2)">2</li> <li onclick="changeCurrent(3)">3</li> <li onclick="changeCurrent(4)">4</li> <li onclick="changeCurrent(5)">5</li> <li onclick="changeCurrent(6)">6</li> </ul>
Below are the steps I am following:- 以下是我正在执行的步骤:-

  1. I am cloning last few items and appending to first and cloning first few items and appending it to last (thanks to post :- http://stackoverflow.com/a/15877302/1098851 ).我正在克隆最后几个项目并附加到第一个并克隆前几个项目并将其附加到最后(感谢发布:- http://stackoverflow.com/a/15877302/1098851 )。 Just to have the infinite effect when I am at first or last item.只是为了当我在第一个或最后一个项目时有无限的效果。

  2. on click of arrow I am transforming the item container with same as Item size, considering the side where I am transforming.单击箭头时,我正在转换与项目大小相同的项目容器,考虑到我正在转换的一侧。

  3. inside setInterval I am checking if its first Item or last and accordingly moving my sliding container.在 setInterval 中,我正在检查它的第一个项目还是最后一个项目,并相应地移动我的滑动容器。

Above code is working fine.上面的代码工作正常。 Just I am facing issues with setIntervals function:- 1. It's transforming the slide very slowly.只是我遇到了 setIntervals 函数的问题:- 1. 它非常缓慢地转换幻灯片。

  1. if I do multiple clicks on arrow, weird effect happens on slide.如果我多次点击箭头,幻灯片上就会出现奇怪的效果。

You just need to a bit better manage timeout你只需要更好地管理timeout

for animation it is much more suitable to use css:对于动画,使用 css 更合适:

transition: all 0.5s; will do the job well.会很好地完成工作。

I updated your example我更新了你的例子

Explanations in comments评论中的解释

 var fragPre = document.createDocumentFragment(), fragPost = document.createDocumentFragment(), clonedPre, clonedPost, selectSlide = document.getElementById("numberOfSlides"), //options numberOfSlides = 3; var items = document.querySelectorAll("#gallery .slider-scroller-inner .item"), len = items.length, current = 1, /* the current item we're looking */ wrapper = document.getElementById("wrapper"), transformVal = 0; /* 1. Cloning last items and appending to first */ for(var i=numberOfSlides ; i > 0 ; i--) { clonedPre = items[items.length-i].cloneNode(true); fragPre.append(clonedPre); } wrapper.insertBefore(fragPre , items[0]); /* . Cloning first items and appending to first */ for(var j = 0 ; j <= numberOfSlides-1 ; j++) { clonedPost = items[j].cloneNode(true); fragPost.append(clonedPost); } wrapper.appendChild(fragPost); /* Slider arrow click function */ var slideWidth=items[0].offsetWidth; var counter = 0; var timer = null; var timeout = null; wrapper.style.transform = "translate3d(" + (-slideWidth) * (numberOfSlides) + "px,0,0)"; function arrowClick(dir) { // if timeout || timer is not null than sliding is processing right now, prevent processing user's actions in this case if (timeout || timer) { return; } timeout = setTimeout(function() { counter = 0; direction = dir; var str = wrapper.style.transform; var left = str.substring(12, str.length - 11); console.log(left); animateSlide(current, left); timeout = null; // <-- setting timeout to null that will mean that function is partly (also will check timer) ready for new user's actions }, 300); } /* slide number click function */ function changeCurrent(curr) { current = curr; wrapper.style.transform = "translate3d(" + -(slideWidth) * (current + (numberOfSlides-1)) + "px,0,0)"; } /* actual sliding effect */ function animateSlide(curr, left) { // if timer is not prevent processing new animation if (timer) { return; } timer = setInterval(function() { if(counter < slideWidth) { counter += 2; // <-- this is the speed of animation. bigger number faster animating transformVal = parseInt(left, 10) + (-(counter) * direction); wrapper.style.transform = "translate3d(" + transformVal + "px,0,0)"; } else { current += direction; cycle = !!(current === 0 || current > len); if (cycle) { current = (current === 0)? len : 1; wrapper.style.transform ="translate3d(" + (-(slideWidth) * (current + (numberOfSlides-1))) + "px,0,0)"; } counter = 0; clearInterval(timer); timer = null; // <-- setting timer to null and now it's ready for another animaton } }, 0); }
 body { margin: 0; padding: 0; } .carousel-slider-wrapper { width: 1200px; margin: 0 auto; position: relative; } .slider-scroller-wrap { overflow: hidden; } .slider-scroller { font-size: 0; white-space: nowrap; position: relative; top: 0; margin: 0; padding: 0; } .slider-scroller-inner { /* transition: .2s ease-out; */ } .slider-scroller-inner { display: flex; width: 100%; position: relative; } .slider-scroller-inner .item { display: inline-block; vertical-align: top; /* padding: 2px; */ box-sizing: border-box; /* border: 1px solid; */ cursor: grab; text-align: center; flex: 0 0 33.33%; } .slider-scroller-inner .item img { max-width: 100%; } button { font: 40px "Courier New"; border: none; box-shadow: 1px 2px 3px #666666; background: #e4e4e4; color: #626262; cursor: pointer; text-align: center; position: absolute; top: 50%; transform: translateY(-50%); height: 70px; z-index: 1; } button.prev { left: 0; } button.next { right: 0; } label, a { font: 14px Georgia; font-style: italic; color: #626262; } #indicators { padding: 0; margin: 1rem 0; overflow: hidden; text-align: center; } #indicators li { padding: .5rem; border-radius: 100%; font-weight: bold; background: #7592bd; display: inline-flex; height: 1.4rem; width: 1.4rem; color: #FFFFFF; text-align: center; cursor: pointer; justify-content: center; align-items: center; margin-right: .3rem; } #indicators li:hover { box-shadow: 1px 2px 3px #333333; }
 <div class="carousel-slider-wrapper"> <button class="prev" type="button" id="prev" onclick="arrowClick(-1)">&lsaquo;</button> <div class="slider-scroller-wrap"> <div class="slider-scroller" id="gallery"> <!-- mask --> <div class="slider-scroller-inner" id="wrapper"> <div class="item"><img src="https://newyse-res.cloudinary.com/image/upload///t_mcms_larger/f_auto/v1511188164/33-2426430.jpg"></div> <div class="item"><img src="https://newyse-res.cloudinary.com/image/upload///t_mcms_larger/f_auto/v1511186177/33-2425761.jpg"></div> <div class="item"><img src="https://newyse-res.cloudinary.com/image/upload///t_mcms_larger/f_auto/v1511186164/33-2425751.jpg"></div> <div class="item"><img src="https://newyse-res.cloudinary.com/image/upload///t_mcms_larger/f_auto/v1511185761/33-2425646.jpg"></div> <div class="item"><img src="https://newyse-res.cloudinary.com/image/upload///t_mcms_larger/f_auto/v1557227665/33-2893456.jpg"></div> <div class="item"><img src="https://newyse-res.cloudinary.com/image/upload///t_mcms_larger/f_auto/v1511970254/33-2437550.jpg"></div> </div> </div> </div> <button class="next" type="button" id="next" onclick="arrowClick(1)">&rsaquo;</button> </div> <ul id="indicators" class=""> <li onclick="changeCurrent(1)">1</li> <li onclick="changeCurrent(2)">2</li> <li onclick="changeCurrent(3)">3</li> <li onclick="changeCurrent(4)">4</li> <li onclick="changeCurrent(5)">5</li> <li onclick="changeCurrent(6)">6</li> </ul>

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

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