0

I have a loop adding/removing the classes on the .master div:

function loopSlide(){
  setTimeout(function(){ $(".master").addClass("one") }, 0);
  setTimeout(function(){ $(".master").removeClass("one") }, 2000);
  setTimeout(function(){ $(".master").addClass("two") }, 2000);
  setTimeout(function(){ $(".master").removeClass("two") }, 4000);
  setTimeout(function(){ $(".master").addClass("three") }, 4000);
  setTimeout(function(){ $(".master").removeClass("three") }, 6000);
  setTimeout(loopSlide, 6000);
}
  
loopSlide()
.master div {
  display: none;
}

.master.one div:nth-child(1) {
  display: block;
}

.master.two div:nth-child(2) {
  display: block;
}

.master.three div:nth-child(3) {
  display: block;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="master">
  <div>1</div>
  <div>2</div>
  <div>3</div>
</div>

Now I am looking for a way, how to stop the loop by clicking on one of the divs (1, 2, 3).

Fiddle

7
  • 1
    you need to set the timeout into a variable and then clear the timeout - developer.mozilla.org/en-US/docs/Web/API/… Commented Sep 16, 2019 at 12:47
  • 1
    A boolean variable which store if the loop is active or not and a click listener on the master's children should lead you to the right direction. Commented Sep 16, 2019 at 12:47
  • Also why not just add the same class to the divs to show them, eg just add an active class Commented Sep 16, 2019 at 13:00
  • @Pete I just simplified the code to show my problem Commented Sep 16, 2019 at 13:22
  • There is something very wrong with the way you are doing things then as you will soon find your code unmanageable and hard to maintain if you need to add more divs due to having repetitive code Commented Sep 16, 2019 at 13:23

2 Answers 2

1

you can try below logic where you can retain class one, two and three and also stop the loop when click on div where you need to clear interval which is saved in a variable

$(document).ready(function(){
     var $master = $('.master');
     var $div = $('.master div');
     var $currentDiv = $('.master div:first');
     $currentDiv.addClass('one');

     var interval = setInterval(function(){
         var $next = $currentDiv.next();
         $master.removeClass('one two three');
         if($next.length>0) {
            $currentDiv = $next;
         } else {
            $currentDiv = $('.master div:first');
         }
         var index = $currentDiv.index();
         if(index == 0) {
           $master.addClass('one');
         } else if(index == 1) {
           $master.addClass('two');
         } else if(index ==2) {
           $master.addClass('three');
         }
  }, 2000);
  
   $div.on('click', function(){
     clearInterval(interval);
   
   });
  
  });
.master div {
  display: none;
}

.master.one div:nth-child(1) {
  display: block;
}

.master.two div:nth-child(2) {
  display: block;
}

.master.three div:nth-child(3) {
  display: block;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.1.1/jquery.min.js"></script>
<div class="master">
  <div >1</div>
  <div>2</div>
  <div>3</div>
</div>

Sign up to request clarification or add additional context in comments.

3 Comments

it works, but it is important to switch classes with names "one", "two", "three" as there is a deeper logic. I just simplified it, to show my problem. So now, the stop is working, but thee class is not changing anymore :S
works perfect. And is there also a way to initially start the whole loop by a click on a button new button?
yes, you can call settimeout inside click handler of the button instead of directly calling it from $(document).ready..
1

reference = setTimeout() returns a value that lets you "cancel" the setTimeout's function execution via clearTimeout( reference )

Store the value returned by setTimeout() then let a click on the <div> clear the timeout

$('.master').on('click', function(evt) { clearTimeout( reference ); } );

Another approach would be to store inside a variable if the loop shoud proceed or not. Change the variable when the users clicks. Check the variable before setTimeout()

var proceed = true;
$('.master').on('click', proceed=false; } );

...

if( proceed ) setTimeout(...

The whole thing becomes

var proceed = true;

loopSlide();

function loopSlide(){
    setTimeout(function(){ $(".master").addClass("one") }, 0);
    setTimeout(function(){ $(".master").removeClass("one") }, 2000);
    setTimeout(function(){ $(".master").addClass("two") }, 2000);
    setTimeout(function(){ $(".master").removeClass("two") }, 4000);
    setTimeout(function(){ $(".master").addClass("three") }, 4000);
    setTimeout(function(){ $(".master").removeClass("three") }, 6000);
    if( proceed )
    {
        setTimeout(loopSlide, 6000);
    }
}

$('.master div').click(function (){
  proceed=false;
});

fiddle

1 Comment

I liked the second approach, but maybe I am too stupid to get this work: jsfiddle.net/b0vxzejh

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.