There is a function that starts when the page is scrolled to a specific place (for example, up to ( top>800 ) If we scroll the page back (( top<800 ), the function will continue to run until it is completely completed.

Question: How to make the function stop if the condition is no longer satisfied? It looks like this:

  function add() { $("ul li").each(function(i, el) { setTimeout(function() { $(el).addClass("active"); }, 0 + (i * 800)); }); } function remove() { $("ul li").each(function(i, el) { $(el).removeClass("active"); }); } $(window).scroll(function() { var top = $(window).scrollTop(); if (top > 300) { add(); } else { remove() } }) 
 body { height: 2800px; } ul { display: block; position: fixed; } li { background: #FF9800; margin: 2px; display: inline-block; padding: 5px; color: #fff; } li.active { background: #8BC34A; } 
 <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.0.0/jquery.min.js"></script> <ul> <li>1</li> <li>2</li> <li>3</li> <li>4</li> <li>5</li> <li>6</li> </ul> 

  • no way, if you hit an else means addcl - not running and there is nothing to interrupt - Grundy
  • ))) if I got into if, then a function is started that starts adding classes with an interval of 800ms, if I scroll up, the function will not stop, it will just be executed else that will not allow it to be run again. Is there no way to interrupt elsee? - Evgeny Shevtsov
  • added a question, look how it works, I don’t know how to interrupt ... - Evgeny Shevtsov

2 answers 2

Make a check in add - if (false) - exit function

 function add() { if (runAddcl == true) { $("ul li").each(function(i, el) { setTimeout(function() { if ($(window).scrollTop() < 300) return; $(el).addClass("active"); }, 0 + (i * 800)); }); } } function remove() { $("ul li").each(function(i, el) { $(el).removeClass("active"); }); } $(window).scroll(function() { var top = $(window).scrollTop(); if (top > 300) { add(); } else { remove() } }) 
 body { height: 2800px; } ul { display: block; position: fixed; } li { background: #FF9800; margin: 2px; display: inline-block; padding: 5px; color: #fff; } li.active { background: #8BC34A; } 
 <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.0.0/jquery.min.js"></script> <ul> <li>1</li> <li>2</li> <li>3</li> <li>4</li> <li>5</li> <li>6</li> </ul> 

  • javascript - single-threaded - while you are spinning in an infinite loop, you cannot set the flag in another place to exit the loop - Grundy
  • It seems to be useful here, event-oriented ... That is, there is no way to realize what I want? - Evgeny Shevtsov
  • @Grundy yes, right, fixed on if ... Thank you - CodeGust
  • @CodeGust and came to the conclusion that I have a question))) - Evgeny Shevtsov
  • @ EvgenyShevtsov And if in the add itself do check $(window).scrollTop()>300 and exit if false ? - CodeGust

The whole problem is in setTimeout, since the entire function is already being executed, and the timers are executed after the time, we need to add a check in the setTimeout function - do we need to still perform this action when time runs out or delete timers, when the function needs to be stopped, via clearTimeout