error at end of loop on slide show

Asked

Viewed 77 times

2

I have the following JS

window.onload = function() {
  var indexAtiva = 0;
  const lis = document.getElementsByClassName('slider').item(0).getElementsByTagName('li');

  function slider() {

    for (i = 0; i < lis.length; i++) {

      if (i != indexAtiva) {
        lis[i].classList.remove('ativa');
      } else {
        lis[i].className = 'ativa'
      }
    }

    if ((indexAtiva + 1) == lis.length) {
      indexAtiva = 0;
    } else {
      indexAtiva++;
    }

    setTimeout(slider, 3000);

  }

  slider();
  
  var slider = document.getElementsByClassName('slider')[0]
  var nav = slider.getElementsByTagName('nav')[0]
  var anterior = nav.getElementsByClassName('anterior')[0]
  var proximo = nav.getElementsByClassName('proximo')[0]
  
  anterior.onclick = function(){
	  prev = indexAtiva - 1	   
	  prev = prev.length ? prev : lis[ lis.length - 1 ];  
	  mostraBloco(prev);
  }
  
  proximo.onclick = function(){
	  next = indexAtiva + 1	   
      next = next.length ? next : lis[0];    
	  mostraBloco(next);	  
  }
// Função para exibir as imagens 
  function mostraBloco(next) {
	  ativa = document.getElementsByClassName('ativa')
	  ativa[0].classList.remove('ativa')  
	  next.className = 'ativa'
  }

}
* {
	margin:0;
	padding:0;
	border:none;
	outline:0;
}

body {
	width:100vw;
}


ul {
	list-style: none;
}
  .fade {
	  -webkit-animation-name: fade;
	  -webkit-animation-duration: 1.5s;
	  animation-name: fade;
	  animation-duration: 1.5s;
  }
  @-webkit-keyframes fade {
	 from {
	opacity: .4
	}
	 to {
	opacity: 1
	}
  }
  @keyframes fade {
	 from {
	opacity: .4
	}
	 to {
	opacity: 1
	}
  }  
@keyframes slider {
    0% {
        transform: scale(1);        
    } 
    100% {
        transform: scale(1.1);     
    }
}  

div.slider {
	position:relative;
	width:100%;
	overflow:hidden;	
}
div.slider ul.slide {
}
div.slider ul.slide li{
	display:none;
}

.ativa{
	display:block !important;	
}

div.slider ul.slide li img {
    position:relative;
	width: 100%;
	animation: slider 1s linear;
	animation-fill-mode: forwards;
}
div.slider ul.slide li span {
    position:absolute;
	width: 100px;
	left: calc(50% - 50px);
	line-height:40px;
    bottom:0;
	text-align:center;
	color:rgb(255,255,255);
	z-index:2;	
}

  div.slider nav {
      position:absolute;
      width:100%;
      height:40px;
      bottom:0;
      background-color:rgba(0,0,0,.5);
      z-index:1;
  }
  div.slider nav button {
      position:absolute;
      width:150px;
      height:100%;
	  cursor:pointer;
  }
  div.slider nav  button.anterior {
      left: 10%;
  }
  div.slider nav  button.proximo {
      right: 10%;
  }
<div class="slider">
  <ul class="slide">
     <li class="ativa">
        <img class="fade" src="_img/_banner/_site/bg_1.jpg" />
        <span>Este é 1</span>
     </li>
     <li>
        <img class="fade" src="_img/_banner/_site/bg_2.jpg" />
        <span>Este é 2</span>
     </li>
  </ul>
  <nav>
    <button class="anterior">Anterior</button>
    <button class="proximo">Próximo</button>
  </nav>
</div>

My goal is to catch a UL with their Lis and show one to one. But not all at once.

The error is as follows: the slide runs normally. But when it arrives at the end, it hangs and the console shows no error.

Where is the error?

Note: if I withdraw the part that is below

slider();

all, then the slider runs normal. That is, the problem should be on the navigation buttons

Follow the online link

http://funerariasaopedro.net.br/novo/index5.php

  • use the snippet to include html + css + js in your question

  • done leandro. insert in question

  • in fact it seems that neither is navigated

2 answers

1


One of the problems is that you created an object with the same function name:

function slider() { and var slider = document.getElementsByClassName('slider')[0]

This will generate conflict because the object slider is no longer a function at this point:

var slider = document.getElementsByClassName('slider')

The solution is either to rename the function or variable, not the two with the same name. For example:

var slider1 = document.getElementsByClassName('slider')[0]
var nav = slider1.getElementsByTagName('nav')[0]

Another redundant thing is the for, that does not require that if within it.

Regarding the buttons, you can take advantage of the function slider() dispensing extra functions, as it did. Just you differentiate the click on the button Previous, placing a parameter true, so that the function knows that it was clicked. In the case of the button Next no need, because the default function already passes the slides forward.

See working:

window.onload = function() {
   var indexAtiva = 0;
   const lis = document.getElementsByClassName('slider').item(0).getElementsByTagName('li');

   function slider(s) {

      for (i = 0; i < lis.length; i++) {
         lis[i].classList.remove('ativa');
      }

      // aqui irá tratar o clique no "Anterior".
      // É preciso tratar de 3 formas diferentes
      // dependendo do valor de indexAtiva.
      // Veja que o valor de indexAtiva, em cada caso,
      // irá receber o valor do índice ativado
      if(s){
         // significa que o próximo a mostrar será o
         // slide de índice 1, então está sendo exibido o 0.
         // neste caso eu ativo o último da array
         if(indexAtiva == 1){
            lis[lis.length-1].className = 'ativa';
            indexAtiva = lis.length-1;
            
         // aqui diz que está exibindo o último,
         // logo próximo será o primeiro (índice 0).
         // Então eu ativo o antepenúltimo da array
         }else if(indexAtiva == 0){
            lis[lis.length-2].className = 'ativa';
            indexAtiva = lis.length-2;
            
          // aqui é quando não for nenhum dos casos anteriores.
          // Eu diminuo 2 índices porque mais a frente será
          // incrementado com +1
         }else{
            lis[indexAtiva-2].className = 'ativa';
            indexAtiva -= 2;
         }
      }else{
         // aqui é quando for clicado o botão "próximo"
         // ou quando nenhum botão for clicado
         lis[indexAtiva].className = 'ativa';
      }

      indexAtiva = indexAtiva + 1 == lis.length ? 0 : indexAtiva+=1;

      tempo = setTimeout(slider, 3000);
   }

   slider();
   
   var slider1 = document.getElementsByClassName('slider')[0]
   var nav = slider1.getElementsByTagName('nav')[0]
   var anterior = nav.getElementsByClassName('anterior')[0]
   var proximo = nav.getElementsByClassName('proximo')[0]
   
   anterior.onclick = function(){
      clearTimeout(tempo);
      slider(true);
   }
   
   proximo.onclick = function(){
      clearTimeout(tempo);
      slider();
   }

}
* {
	margin:0;
	padding:0;
	border:none;
	outline:0;
}

body {
	width:100vw;
}


ul {
	list-style: none;
}
  .fade {
	  -webkit-animation-name: fade;
	  -webkit-animation-duration: 1.5s;
	  animation-name: fade;
	  animation-duration: 1.5s;
  }
  @-webkit-keyframes fade {
	 from {
	opacity: .4
	}
	 to {
	opacity: 1
	}
  }
  @keyframes fade {
	 from {
	opacity: .4
	}
	 to {
	opacity: 1
	}
  }  
@keyframes slider {
    0% {
        transform: scale(1);        
    } 
    100% {
        transform: scale(1.1);     
    }
}  

div.slider {
	position:relative;
	width:100%;
	overflow:hidden;	
}
div.slider ul.slide {
}
div.slider ul.slide li{
	display:none;
}

.ativa{
	display:block !important;	
}

div.slider ul.slide li img {
    position:relative;
	width: 100%;
	animation: slider 1s linear;
	animation-fill-mode: forwards;
  height: 180px;
}
div.slider ul.slide li span {
    position:absolute;
	width: 100px;
	left: calc(50% - 50px);
	line-height:40px;
    bottom:0;
	text-align:center;
	color:rgb(255,255,255);
	z-index:2;	
}

  div.slider nav {
      position:absolute;
      width:100%;
      height:40px;
      bottom:0;
      background-color:rgba(0,0,0,.5);
      z-index:1;
  }
  div.slider nav button {
      position:absolute;
      width:150px;
      height:100%;
	  cursor:pointer;
  }
  div.slider nav  button.anterior {
      left: 10%;
  }
  div.slider nav  button.proximo {
      right: 10%;
  }
<div class="slider">
  <ul class="slide">
     <li class="ativa">
        <img class="fade" src="http://funerariasaopedro.net.br/novo/_img/_banner/_site/bg_1.jpg" />
        <span>Este é 1</span>
     </li>
     <li>
        <img class="fade" src="http://funerariasaopedro.net.br/novo/_img/_banner/_site/bg_2.jpg" />
        <span>Este é 2</span>
     </li>
     <li>
        <img class="fade" src="https://www.cleverfiles.com/howto/wp-content/uploads/2016/08/mini.jpg" />
        <span>Este é 3</span>
     </li>
     <li>
        <img class="fade" src="https://www.salford.ac.uk/__data/assets/image/0008/890072/varieties/lightbox.jpg" />
        <span>Este é 4</span>
     </li>
  </ul>
  <nav>
    <button class="anterior">Anterior</button>
    <button class="proximo">Próximo</button>
  </nav>
</div>

  • got it. only another problem has arisen. the next and previous buttons only rotate inside each loop. That is, if it is in the last image of a loop it does not pass to the first of the next loop

  • Okay, thanks, on hold

  • it actually feels like you’re not even sailing

  • it is my impression or the previous button was the same as the next?

  • See if you can handle it now.

  • not only solved it but it was perfect for me. Thank you. Now I will study this code of yours.

  • Blz... I will add some comments on the code to help you understand the click part on "previous".

Show 2 more comments

0

I think I found the error in the buttons:

in the block

prev = indexAtiva - 1      
prev = prev.length ? prev : lis[ lis.length - 1 ];  
mostraBloco(prev);

the logic is slightly wrong. That’s why, say: the maximum index is 4. It’s currently on the fifth slide (index 4).

prev = 4 - 1 // =3
prev = prev.length ? prev : lis[ lis.length - 1 ];// false, o valor de prev é 3 aqui, nunca vai executar.

the same error occurs on the other button. The solution is simple: make the condition without increasing/decreasing. If true, go back to zero/forward to 4. If false, add/remove 1. This way:

prev = indexAtiva; 
prev == 0 ? lis[indexAtiva] = lis[lis.length] : lis[ lis[indexAtiva] - 1 ];
mostraBloco(prev);

next = indexAtiva
next == lis.length ? lis[indexAtiva] = lis[0] : lis[ lis[indexAtiva] + 1 ];
mostraBloco(next);

(I made new response because I could not comment on the response of the dvd)

  • Sorry, Voce said the maximum index is 4. If this refers to the number of images, at the moment there are only 2 images and not 4. But this should not be counted like this, after all this number can be changed depending on the situation

  • index 4 was an example, I didn’t know the limit, I assumed there were 5 images to illustrate. If the current limit is 2, then replace the value of 4 with 2 in the example and give in the same. On the part of should not be counted so because the amount of slides can change, that you are correct and with the knowledge that I have here I can not think of a way to direct exactly to the beginning or end of the list regardless of how much information you have, I just tried to explain why the 'if' wasn’t working properly

  • Oh Mateu, thank you very much. I got it. but I think the way you put it is not fucnionando the buttons. I will look for the error. You’ve helped enough, buddy!

  • I made a lot of mistakes in the example I gave, try now. (sorry for the mess I made before) Prev = indexAtiva; Prev = 0 ? lis[lis.length] : lis[ lis.length - 1 ]; mostraBloco(Prev); next = indexAtiva next = list.length ? lis[0] : lis[ lis.length + 1 ]; mostraBloco(next); . ....

  • Here, take a look if I did it right. Because you don’t want to change the images when you click the.http://funerariasaopedro.net.br/novo/index5.phpbuttons

  • There is some problem still on the page, the buttons do not work yet, but it is for another reason. If you open the console you will see "Uncaught Typeerror: slider.getelementsbytagname is not a Function at window.onload". I don’t know much about referencing objects in pure js, I’ve always used jQuery, so I won’t be able to help you with this, but because the error shows error in line 3 of your script. I’ll check it out and see if I can find the mistake for you.

  • I found it. In the variable 'Nav', you referred to the variable 'slide' as 'slider' with the R at the end, is causing error on the page. Try to solve this and check if the buttons work.

  • In fact, I found another error in the script I wrote myself. Sigh. em lis[ lis.length + 1 ], the correct would be lis[ Indexativa + 1], or -1 on the other button. Otherwise it will not increase or decrease the position of the list, it will add or remove items from the list as if it were a new value in an array, and in the 'true'' condition of if, it would have to be lis[indexAtiva] = lis[lis.length], or in the other button, = lis[0] btw, on the 'next' button you have typed 'list' instead of lis, and when comparing Prev/next with something use == instead of =.

  • I changed it but it still doesn’t change the images

  • Changes your solution to the most complete?

  • All right, check now

  • where are you? You changed the question? it didn’t work! I’ll update it online! http://funerariasaopedro.net.br/novo/index4.php

Show 7 more comments

Browser other questions tagged

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