How to make this slideshow infinite?

Asked

Viewed 973 times

5

It’s a passing carousel, but the only way I could do it was like this: when it comes to the last slide, it goes back to the first one, making a kind of "return transition" to the beginning.

Question: I would like the slides to be in an infinite loop. In the end, the first one would be pushing the last one, if you know what I mean. If you have any questions, please comment that I will try to explain better 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>
<div class="box-carrossel">			
				<ul class="carrossel">
					<li class="item">slide  1<img src="http://i.imgur.com/9uibBZz.png" /> </li>
					<li class="item">slide  2<img src="http://i.imgur.com/SN10FH8.png" /> </li>
					<li class="item">slide 3<img src="http://i.imgur.com/3Mgc4kt.png" /> </li>		
					<li class="item"> slide 4<img src="http://i.imgur.com/eeGWPqv.png" /> </li>	
					<li class="item">slide  5<img src="http://i.imgur.com/SN10FH8.png" /> </li>				
				</ul>			
		</div>

  • 1

    Are gambiarras valid? I think I have a solution. : P

  • Yes, Inkeliz. rs

2 answers

7


As it is "rotating infinity", it has to completely eliminate the movement of the "rail":

In the HTML and CSS part we gave a "dry" eliminating unnecessary elements, taking advantage of these features:

  • Using inline-block in a container with white-space: nowrap the elements are all in one line, without needing a div extra;

  • thus, the overflow:hidden hides the slides too much, leaving only the main and what is entering the frame;

  • as a consequence, we can set the slides with 100% width, so if you need to adjust the layout, just change the width of the .container;

  • the class item is unnecessary as we can use the child selector >*.

Then comes the logic of JS:

  • At each intervalo we use Animate to move the first slide 100% to the left, shifting its margin;

  • Using the callback from Animate (fourth parameter) we define a function that takes this slide that just left the screen, and puts it at the end of the list, and Zera its margin for the next round;

  • the callback uses this, in order to work with more than one slider on the same page (see the following demo).

Who moves in this logic is only the first item, actually leaving the screen and going to the end of the line. Not a copy at the end of the queue, but the item itself that changes position.

We eliminated the concept of the trail, then its carousel became infinite in fact, because it no longer comes to the case the amount of items.

If you change anything in layout and quantity, just adjust the HTML, and at most the CSS, helping a lot in the reuse of 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>
<ul class="carrossel">
   <li>Slide 1<br><img src="http://i.imgur.com/9uibBZz.png"></li>
   <li>Slide 2<br><img src="http://i.imgur.com/SN10FH8.png"></li>
   <li>Slide 3<br><img src="http://i.imgur.com/3Mgc4kt.png"></li>
   <li>Slide 4<br><img src="http://i.imgur.com/eeGWPqv.png"></li>
   <li>Slide 5<br><img src="http://i.imgur.com/SN10FH8.png"></li>
</ul>
<ul class="carrossel dois">
   <li>Gato 1<br><img src="http://i.stack.imgur.com/f1HTd.png"></li>
   <li>Gato 2<br><img src="http://i.stack.imgur.com/eTin1.png"></li>
   <li>Gato 3<br><img src="http://i.stack.imgur.com/87KH0.png"></li>
</ul>

3

My idea was this, remembering that maybe it’s not the best:

If the controller is greater than the number of slide he plays the first slide to the last:

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

However, we have to fix a margin-left for this to work, it will get the width necessary:

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

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

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

Now it’s ready.

The change in animate, in the end, it is only to give compatibility in both cases (when it was not exhausted and when it ran out of slides), as it would not give to the controller as a multiplier, you now use the current value of margin-left "added" with more 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 and with the previously fixed margin will add with the width.

In short:

When the last slide arrives it will enter a loop of -1300px for -1500px and always copying the first slide to the last. ;)

$(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>
<div class="box-carrossel">
  <ul class="carrossel">
    <li class="item">slide 1
      <img src="http://i.imgur.com/9uibBZz.png" />
    </li>
    <li class="item">slide 2
      <img src="http://i.imgur.com/SN10FH8.png" />
    </li>
    <li class="item">slide 3
      <img src="http://i.imgur.com/3Mgc4kt.png" />
    </li>
    <li class="item">slide 4
      <img src="http://i.imgur.com/eeGWPqv.png" />
    </li>
    <li class="item">slide 5
      <img src="http://i.imgur.com/SN10FH8.png" />
    </li>
  </ul>
</div>

Browser other questions tagged

You are not signed in. Login or sign up in order to post.