setInterval does not stop after restarted

Asked

Viewed 75 times

-3

I’m trying to create a slideshow but customized without relying on third party library (save, jQuery);

The goal is:

  • The slide rotate endlessly.

  • When passing the mouse on slide, he must stop;

  • By leaving the slide, he must keep running from where he left off!

The problem is:
When passing the mouse again the interval should stop. But it’s not stopping.

function intervalo () {
$(".slider > #next").click ();
}

var interval = setInterval(intervalo,4000);

$(".slider > ul > li").mouseover(function(){
clearInterval(interval);
}).mouseout(function(){
interval = setInterval(intervalo,4000);
});

$(".slider > #back").click ( function(){
	var liMover = $('.slider ul li:last-of-type'); // copia o conteudo da última
	$('slider ul li:last-of-type').remove(); // remove a última
	$(liMover).insertBefore('.slider ul li:first-of-type'); // insere antes da primeira
});

$(".slider > #next").click ( function(){
	var liMover = $('.slider ul li:first-of-type'); // copia o conteudo da primeira
	$('.slider ul li:first-of-type').remove(); // remove a primeira
	$(liMover).insertAfter('.slider ul li:last-of-type'); // insere depois da última
});	
* {
	margin: 0;
	padding: 0;
}

body {
		display: flex;
		width: 1000px;
		margin: 0 auto;
}

.slider {
	position: relative;
	display: flex;
	flex-direction: column;
	width: 1000px;
	height: 150px;
	overflow: hidden;	
	border: 1px solid #000;
}

.slider > ul {
	display: flex;
	flex-wrap: wrap;
	width: 5000px;	
}

.slider > ul > li {
	display: flex;
	width: 500px;
	height: 150px;
}

.slider > button {
	position: absolute;
	display: flex;
	justify-content: center;
	top: calc(45% - 15px);
	width: 30px;
	height: 30px;
	opacity: .2
}

.slider > button:hover {
	opacity: 1;
	cursor: pointer;
}

.slider > button#back {
	left: 10px;
}

.slider > button#next {
	right: 10px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>

<div class="slider">

	<ul>
	  <li> Slide  1 </li>
	  <li> Slide  2 </li>
	  <li> Slide  3 </li>
	  <li> Slide  4 </li>
	</ul>		

	<button id="back"> BACK </button>
	<button id="next"> NEXT </button>

</div>

What will be wrong!

  • Just one detail: The solution presented in https://answall.com/questions/115615/setinterval-n%C3%A3o-funciona-ap%C3%B3s-clearinterval, has exactly the same flaw! Although both solutions work well at first!

  • Then I tested on Chrome, with windows 10, hp notebook tsc15 and it worked. Decreases the interval to a second. Explain to me better the failure condition of this code.

  • 1

    So @Augustovasques, just to give you a satisfaction. In my code, it was too much code. kkk. It was just take out $('.slider ul li:first-of-type'). remove(); as the answer of the colleague below, that worked out well!. Thank you for the attention!

1 answer

3


What happens is that when you use the remove() in the li it is no longer the same element and loses the application of events mouseover and mouseout. Even it is not only after the first time of a mouse over that stops working, after a complete cycle of the running slide also does not work because all li were replaced. remove is not necessary when using insertAfter the position of li is changed and therefore it will no longer be at the top of the list.

Code working (I changed some things of style and speed just to make it easier to see):

<html>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>


<script>

$().ready(() => {

$(".slider > #back").click ( function(){
    var liMover = $('.slider ul li:last-of-type'); // copia o conteudo da última
    //$('slider ul li:last-of-type').remove(); // remove a última
    $(liMover).insertBefore('.slider ul li:first-of-type'); // insere antes da primeira
});

$(".slider > #next").click ( function(){
    var liMover = $('.slider ul li:first-of-type'); // copia o conteudo da primeira
    //$('.slider ul li:first-of-type').remove(); // remove a primeira
    $(liMover).insertAfter('.slider ul li:last-of-type'); // insere depois da última
});

function intervalo () {
$(".slider > #next").click ();
}

interval = setInterval(intervalo,1000);

$(".slider > ul > li").mouseover(function(){
    clearInterval(interval);
}).mouseout(function(){
    interval = setInterval(intervalo,1000);
});

}); 

</script>

<style>
* {
    margin: 0;
    padding: 0;
}

body {
        display: flex;
        width: 1000px;
        margin: 0 auto;
}

.slider {
    position: relative;
    display: flex;
    flex-direction: column;
    width: 1000px;
    height: 200px;
    overflow: hidden;   
    border: 1px solid #000;
}

.slider > ul {
    display: flex;
    flex-wrap: wrap;
    width: 5000px;  
}

.slider > ul > li {
    display: flex;
    width: 500px;
    height: 150px;
    margin: 10px;
}

.slider > ul > li:hover {
    cursor: crosshair;
}

.slider > button {
    position: absolute;
    display: flex;
    justify-content: center;
    top: calc(45% - 15px);
    width: 30px;
    height: 30px;
    opacity: .2
}

.slider > button:hover {
    opacity: 1;
    cursor: pointer;
}

.slider > button#back {
    left: 10px;
}

.slider > button#next {
    right: 10px;
}
</style>

<body>

<div class="slider">

    <ul>
      <li style="background: #cce5ff;"> Slide  1 </li>
      <li style="background: #ffe5e5;"> Slide  2 </li>
      <li style="background: #3399ff;"> Slide  3 </li>
      <li style="background: #ff9999;"> Slide  4 </li>
    </ul>       

    <button id="back"> BACK </button>
    <button id="next"> NEXT </button>

</div>
</body>

</html>

See working here.

  • Boy, it worked out! That’s right! Now, can you, of course, if I’m not asking too much, add, or tell me how to make this transition not happen abruptly? Like, a transition effect! But the answer I needed you already gave. Inclusive , I tested in my code, and was just remove the line from . remove that worked!

  • I don’t know yet, but this code here does something similar using classes: https://jsfiddle.net/239pcojn/2/

  • I forgot to comment that it’s good to put your code inside jQuery ready() to ensure that you only try to associate the events (in particular onclick() of the buttons) after the DOM is loaded.

  • ah yes, so I put js after html!

Browser other questions tagged

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