How to make this slideshow infinite?

5

It's a passing carousel, but the only way I was able to do it was like this: when it arrives on the last slide, it goes back to the first, doing a sort of "return transition" at the beginning.

Question: I would like the slides to be in infinite loop. That in the end, the first would push the last, if you understand me. If you have any questions, please comment that I will try to explain further and edit the question.

Code below:

$(function(){
	//número do slide atual (1 porque pega do primeiro e vai incrementando)
	var controller = 1;

	//identifica o número de slides (<li>)
	var numSlides = $('.carrossel .item').length;

	// tempo de transição
	var time = 600;

	//loop que gerencia a troca de slides
	setInterval(function(){
		//se o slide atual não for o último, anima para o próximo
		if(controller < numSlides){

			//animação do trilho para o próximo slide
			$('.carrossel').animate({
			'margin-left': '-'+controller*300+'px'
			}, time);

			//incrementa a var controller ao passar um slide
			controller ++;
		}
		//se o slide atual for o último, anima para o primeiro
		else{

			//zera o margin-left do trilho de slides (ul)
			$('.carrossel').animate({
			'margin-left': '0px'
			}, time/2);

			//volta o controller para 1
			controller = 1;
		}
	}, time+2500);
})
* {
	margin: 0;
	padding: 0;
	border: 0;
	list-style: none;
	box-sizing: border-box;
}

.box-carrossel {
	width: 300px;
	margin: 10% auto;
	position: relative;	
	background: #fff;
	box-shadow: 0 0 5px 1px black;
	overflow: hidden;

}

.carrossel {
	width: 1000%;
	background: #fff;
	float: left;
	list-style: none;
}

.carrossel .item {
	float: left;
	width: 300px;	
	background: #2E9ABE;
	

}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script><divclass="box-carrossel">			
				<ul class="carrossel">
					<li class="item">slide  1<img src="http://i.imgur.com/9uibBZz.png"/></li><liclass="item">slide  2<img src="http://i.imgur.com/SN10FH8.png"/></li><liclass="item">slide 3<img src="http://i.imgur.com/3Mgc4kt.png"/></li><liclass="item"> slide 4<img src="http://i.imgur.com/eeGWPqv.png"/></li><liclass="item">slide  5<img src="http://i.imgur.com/SN10FH8.png" /> </li>				
				</ul>			
		</div>
    
asked by anonymous 22.01.2017 / 12:07

2 answers

7

As it is "infinite rotating", you can completely eliminate the movement of the "rail":

In the part of HTML and CSS we have made a "wipe" eliminating unnecessary elements, taking advantage of these features:

  • so inline-block hides the slides too much, leaving only the main and what's going on in the frame;

  • As a consequence, we can set the slides to width%, so if you need to adjust the layout, simply change the width of the white-space: nowrap ;

  • class div is unnecessary because we can use the overflow:hidden child selector.

Next comes the logic of JS:

  • Every 100% we use the animate to move the first slide .container to the left, shifting its margin;

  • Using the callback of the animate (fourth parameter) we define a function that takes that slide that has just left the screen, and puts it at the bottom of the list, and zeroes its margin to the next lap;

  • callback uses item to work with more than one slider on the same page (see the demo below).

Whoever shifts this logic is just the first item, actually leaving the screen and going to the end of the queue. It is not a copy at the end of the queue, but rather the same item that changes position.

We have eliminated the concept of the rail, then its carousel has become infinite indeed, since the number of items is no longer relevant.

If you change anything in layout and quantity, you just have to adjust HTML, and at most CSS, helping a lot in reusing code for dynamically generated pages.

$(function() {
   var duracao = 600;
   var intervalo = 2400;

   setInterval(function() {
      $('.carrossel>*:first-child').animate({'margin-left': '-100%'}, duracao, 'linear',
         function() {$(this).appendTo(this.parentElement).css('margin-left', '0');}
      )
   }, intervalo);
})
* {
   margin:0;
   padding:0;
   box-sizing: border-box;
}
.carrossel {
   width:330px;
   overflow:hidden;
   white-space:nowrap;
   background:#2E9ABE;
   list-style:none;
}

.carrossel>* {
   display: inline-block;
   width: 100%;
}

.dois {               /* Só para demonstrar um segundo slider  */
   background: #c90;
   position:absolute;
   width:220px;       /* Largura diferente do primeiro         */
   left:350px;
   top:0;
   text-align:center;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script><ulclass="carrossel">
   <li>Slide 1<br><img src="http://i.imgur.com/9uibBZz.png"></li><li>Slide2<br><imgsrc="http://i.imgur.com/SN10FH8.png"></li>
   <li>Slide 3<br><img src="http://i.imgur.com/3Mgc4kt.png"></li><li>Slide4<br><imgsrc="http://i.imgur.com/eeGWPqv.png"></li>
   <li>Slide 5<br><img src="http://i.imgur.com/SN10FH8.png"></li></ul><ulclass="carrossel dois">
   <li>Gato 1<br><img src="http://i.stack.imgur.com/f1HTd.png"></li><li>Gato2<br><imgsrc="http://i.stack.imgur.com/eTin1.png"></li>
   <li>Gato 3<br><img src="http://i.stack.imgur.com/87KH0.png"></li>
</ul>
    
22.01.2017 / 14:46
3

My idea was as follows, remembering that maybe it's not the best:

If the controller is greater than the number of slide it throws the first slide to the last:

$('.carrossel .item').eq(0).appendTo(".carrossel");

However, we have to set margin-left to make this work, this will get the width needed:

var width = $('.carrossel .item').eq(0).width();

Now, we need the carousel to understand that the fourth (now penultimate) element is with margin-left fixed of width * 4 , in other words: width * (numSlide - 2) .

$('.carrossel').css('margin-left', '-' + ((numSlides - 2) * width) + 'px');

Now it's ready.

The change in animate , in the end, is only to give compatibility in both cases (when it did not run out and when the slides ran out), since it would not give controller as a multiplier, it started to use the current value of margin-left "added" plus width :

$('.carrossel').animate({
   'margin-left': ( parseInt($('.carrossel').css('margin-left')) - width ) + 'px'
}, time);

Whenever you finish the slides, it will copy the first and play to the last one and with the previously set margin will add with width .

In short:

When the last slide arrives it will go into a loop from -1300px to -1500px and always copying the first slide to the last one. ;)

$(function() {
  // Número do slide atual (1 porque pega do primeiro e vai incrementando)
  var controller = 1;

  // Identifica o número de slides (<li>)
  var numSlides = $('.carrossel .item').length;

  // Identifica o tamanho
  var width = $('.carrossel .item').eq(0).width();

  // Tempo de transição
  var time = 600;

  // Loop que gerencia a troca de slides
  setInterval(function() {

    // Se o slide não estiver "esgotado"
    if (controller < numSlides) {

      //incrementa a var controller ao passar um slide
      controller++;

      // Se o slide "acabar"
    } else {

      // Move o primeiro para o ultimo
      $('.carrossel .item').eq(0).appendTo(".carrossel");

      // Fixa a margem de ( (Total de slide) - 1 ) * Largura
      $('.carrossel').css('margin-left', '-' + ((numSlides - 2) * width) + 'px');

    }

    // Animação do trilho para o próximo slide
    $('.carrossel').animate({
      'margin-left': ( parseInt($('.carrossel').css('margin-left')) - width ) + 'px'
    }, time);

  }, time + 2500);
})
* {
  margin: 0;
  padding: 0;
  border: 0;
  list-style: none;
  box-sizing: border-box;
}
.box-carrossel {
  width: 300px;
  margin: 10% auto;
  position: relative;
  background: #fff;
  box-shadow: 0 0 5px 1px black;
  overflow: hidden;
}
.carrossel {
  width: 1000%;
  background: #fff;
  float: left;
  list-style: none;
}
.carrossel .item {
  float: left;
  width: 300px;
  background: #2E9ABE;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script><divclass="box-carrossel">
  <ul class="carrossel">
    <li class="item">slide 1
      <img src="http://i.imgur.com/9uibBZz.png"/></li><liclass="item">slide 2
      <img src="http://i.imgur.com/SN10FH8.png"/></li><liclass="item">slide 3
      <img src="http://i.imgur.com/3Mgc4kt.png"/></li><liclass="item">slide 4
      <img src="http://i.imgur.com/eeGWPqv.png"/></li><liclass="item">slide 5
      <img src="http://i.imgur.com/SN10FH8.png" />
    </li>
  </ul>
</div>
    
22.01.2017 / 12:48