JavaScript: Adding setInterval() dynamically in loop, and clearing each instance separately












1














I want to loop over every element with a particular class, then add an interval and timeout to each element. The timeout will change its class in n seconds and the interval will repeat x seconds.



However, I also want the user to stop the intervals individually by clicking on the element of their choice, rather than clearing all the Intervals (or the last timeout) at once. Is there a way to set individual Interval instances per iteration in a loop? And if so, how do you then refer to these instances individually later?



Noted where I get stuck in the logic:



 var myInterval;
$('.my-elements').each(function(i){
var thisElement = $(this)

//add class every 2000 milliseconds
//At a loss on how to make dynamic/relative to interation
setInterval(function(){

$(thisElement).addClass("active");
//remove class after 200 milliseconds
var myInterval = setTimeout(function(){ $(thisElement).removeClass("active") },200)


}, 2000)

$(thisElement).click(function(){
//AT A LOSS
//stop interval for this element;
})

})









share|improve this question





























    1














    I want to loop over every element with a particular class, then add an interval and timeout to each element. The timeout will change its class in n seconds and the interval will repeat x seconds.



    However, I also want the user to stop the intervals individually by clicking on the element of their choice, rather than clearing all the Intervals (or the last timeout) at once. Is there a way to set individual Interval instances per iteration in a loop? And if so, how do you then refer to these instances individually later?



    Noted where I get stuck in the logic:



     var myInterval;
    $('.my-elements').each(function(i){
    var thisElement = $(this)

    //add class every 2000 milliseconds
    //At a loss on how to make dynamic/relative to interation
    setInterval(function(){

    $(thisElement).addClass("active");
    //remove class after 200 milliseconds
    var myInterval = setTimeout(function(){ $(thisElement).removeClass("active") },200)


    }, 2000)

    $(thisElement).click(function(){
    //AT A LOSS
    //stop interval for this element;
    })

    })









    share|improve this question



























      1












      1








      1







      I want to loop over every element with a particular class, then add an interval and timeout to each element. The timeout will change its class in n seconds and the interval will repeat x seconds.



      However, I also want the user to stop the intervals individually by clicking on the element of their choice, rather than clearing all the Intervals (or the last timeout) at once. Is there a way to set individual Interval instances per iteration in a loop? And if so, how do you then refer to these instances individually later?



      Noted where I get stuck in the logic:



       var myInterval;
      $('.my-elements').each(function(i){
      var thisElement = $(this)

      //add class every 2000 milliseconds
      //At a loss on how to make dynamic/relative to interation
      setInterval(function(){

      $(thisElement).addClass("active");
      //remove class after 200 milliseconds
      var myInterval = setTimeout(function(){ $(thisElement).removeClass("active") },200)


      }, 2000)

      $(thisElement).click(function(){
      //AT A LOSS
      //stop interval for this element;
      })

      })









      share|improve this question















      I want to loop over every element with a particular class, then add an interval and timeout to each element. The timeout will change its class in n seconds and the interval will repeat x seconds.



      However, I also want the user to stop the intervals individually by clicking on the element of their choice, rather than clearing all the Intervals (or the last timeout) at once. Is there a way to set individual Interval instances per iteration in a loop? And if so, how do you then refer to these instances individually later?



      Noted where I get stuck in the logic:



       var myInterval;
      $('.my-elements').each(function(i){
      var thisElement = $(this)

      //add class every 2000 milliseconds
      //At a loss on how to make dynamic/relative to interation
      setInterval(function(){

      $(thisElement).addClass("active");
      //remove class after 200 milliseconds
      var myInterval = setTimeout(function(){ $(thisElement).removeClass("active") },200)


      }, 2000)

      $(thisElement).click(function(){
      //AT A LOSS
      //stop interval for this element;
      })

      })






      javascript loops settimeout






      share|improve this question















      share|improve this question













      share|improve this question




      share|improve this question








      edited Nov 14 '18 at 23:05







      auto

















      asked Nov 14 '18 at 23:00









      autoauto

      3901319




      3901319
























          2 Answers
          2






          active

          oldest

          votes


















          0














          Assign the setInterval call to myInterval and remove the global variable myInterval rather than the setTimeout, also no need to wrap your element in another jquery call



          $('.my-elements').each(function(i){
          var thisElement = $(this);

          //add class every 2000 milliseconds
          var myInterval = setInterval(function(){
          thisElement.addClass("active");
          //remove class after 200 milliseconds -- At a loss on how to make dynamic/relative to interation
          setTimeout(function(){ $(thisElement).removeClass("active") },200);
          }, 2000)

          thisElement.click(function(){
          clearTimeout(myInterval);
          });
          })





          share|improve this answer





















          • I confused "Interval" and "Timeout" and updated the question, but your answer still seems to apply. Thank you. So, clearTimeout(myInterval) still applies to each iteration individually if in the loop, and doesn't get erased on the next iteration? Makes sense. Thank you.
            – auto
            Nov 14 '18 at 23:10



















          0














          Since setting a timeout actually returns a numerical ID of the timer, you can simply store/cache the timer associated with each element in a custom jQuery .data() object.



          Note that in the example below I have set the timer from your 200ms to 1000ms so that you can see the changes better.






          $('.my-elements').each(function(i) {
          var $thisElement = $(this);

          //add class every 2000 milliseconds
          setInterval(function() {

          $thisElement.addClass("active");
          var classRemovalTimer = setTimeout(function() {
          $thisElement.removeClass("active")
          }, 1000);

          // Store this class removal timer in jQuery data object
          $thisElement.data('class-removal-timer-id', classRemovalTimer);

          }, 2000);

          $thisElement.click(function() {
          // Check if timer exists for the element.
          // If it does, clear it
          var classRemovalTimer = $thisElement.data('class-removal-timer-id')
          if (classRemovalTimer) {
          window.clearTimeout(classRemovalTimer);
          }
          })

          })

          .active {
          background-color: red;
          color: white;
          }

          <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
          <div class="my-elements">1</div>
          <div class="my-elements">2</div>
          <div class="my-elements">3</div>
          <div class="my-elements">4</div>
          <div class="my-elements">5</div>





          Some additional pro-tips:




          • You are double wrapping your $(this) element, by first assigning it to thisElement and then wrapping $(thisElement) later. You only need to do that once

          • Read up about how you can take advantage of jQuery's .data() object/store






          share|improve this answer





















          • Okay. Interesting. I will try it. Thank you.
            – auto
            Nov 14 '18 at 23:21











          Your Answer






          StackExchange.ifUsing("editor", function () {
          StackExchange.using("externalEditor", function () {
          StackExchange.using("snippets", function () {
          StackExchange.snippets.init();
          });
          });
          }, "code-snippets");

          StackExchange.ready(function() {
          var channelOptions = {
          tags: "".split(" "),
          id: "1"
          };
          initTagRenderer("".split(" "), "".split(" "), channelOptions);

          StackExchange.using("externalEditor", function() {
          // Have to fire editor after snippets, if snippets enabled
          if (StackExchange.settings.snippets.snippetsEnabled) {
          StackExchange.using("snippets", function() {
          createEditor();
          });
          }
          else {
          createEditor();
          }
          });

          function createEditor() {
          StackExchange.prepareEditor({
          heartbeatType: 'answer',
          autoActivateHeartbeat: false,
          convertImagesToLinks: true,
          noModals: true,
          showLowRepImageUploadWarning: true,
          reputationToPostImages: 10,
          bindNavPrevention: true,
          postfix: "",
          imageUploader: {
          brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
          contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
          allowUrls: true
          },
          onDemand: true,
          discardSelector: ".discard-answer"
          ,immediatelyShowMarkdownHelp:true
          });


          }
          });














          draft saved

          draft discarded


















          StackExchange.ready(
          function () {
          StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53310007%2fjavascript-adding-setinterval-dynamically-in-loop-and-clearing-each-instance%23new-answer', 'question_page');
          }
          );

          Post as a guest















          Required, but never shown

























          2 Answers
          2






          active

          oldest

          votes








          2 Answers
          2






          active

          oldest

          votes









          active

          oldest

          votes






          active

          oldest

          votes









          0














          Assign the setInterval call to myInterval and remove the global variable myInterval rather than the setTimeout, also no need to wrap your element in another jquery call



          $('.my-elements').each(function(i){
          var thisElement = $(this);

          //add class every 2000 milliseconds
          var myInterval = setInterval(function(){
          thisElement.addClass("active");
          //remove class after 200 milliseconds -- At a loss on how to make dynamic/relative to interation
          setTimeout(function(){ $(thisElement).removeClass("active") },200);
          }, 2000)

          thisElement.click(function(){
          clearTimeout(myInterval);
          });
          })





          share|improve this answer





















          • I confused "Interval" and "Timeout" and updated the question, but your answer still seems to apply. Thank you. So, clearTimeout(myInterval) still applies to each iteration individually if in the loop, and doesn't get erased on the next iteration? Makes sense. Thank you.
            – auto
            Nov 14 '18 at 23:10
















          0














          Assign the setInterval call to myInterval and remove the global variable myInterval rather than the setTimeout, also no need to wrap your element in another jquery call



          $('.my-elements').each(function(i){
          var thisElement = $(this);

          //add class every 2000 milliseconds
          var myInterval = setInterval(function(){
          thisElement.addClass("active");
          //remove class after 200 milliseconds -- At a loss on how to make dynamic/relative to interation
          setTimeout(function(){ $(thisElement).removeClass("active") },200);
          }, 2000)

          thisElement.click(function(){
          clearTimeout(myInterval);
          });
          })





          share|improve this answer





















          • I confused "Interval" and "Timeout" and updated the question, but your answer still seems to apply. Thank you. So, clearTimeout(myInterval) still applies to each iteration individually if in the loop, and doesn't get erased on the next iteration? Makes sense. Thank you.
            – auto
            Nov 14 '18 at 23:10














          0












          0








          0






          Assign the setInterval call to myInterval and remove the global variable myInterval rather than the setTimeout, also no need to wrap your element in another jquery call



          $('.my-elements').each(function(i){
          var thisElement = $(this);

          //add class every 2000 milliseconds
          var myInterval = setInterval(function(){
          thisElement.addClass("active");
          //remove class after 200 milliseconds -- At a loss on how to make dynamic/relative to interation
          setTimeout(function(){ $(thisElement).removeClass("active") },200);
          }, 2000)

          thisElement.click(function(){
          clearTimeout(myInterval);
          });
          })





          share|improve this answer












          Assign the setInterval call to myInterval and remove the global variable myInterval rather than the setTimeout, also no need to wrap your element in another jquery call



          $('.my-elements').each(function(i){
          var thisElement = $(this);

          //add class every 2000 milliseconds
          var myInterval = setInterval(function(){
          thisElement.addClass("active");
          //remove class after 200 milliseconds -- At a loss on how to make dynamic/relative to interation
          setTimeout(function(){ $(thisElement).removeClass("active") },200);
          }, 2000)

          thisElement.click(function(){
          clearTimeout(myInterval);
          });
          })






          share|improve this answer












          share|improve this answer



          share|improve this answer










          answered Nov 14 '18 at 23:05









          dotconnordotconnor

          1,062120




          1,062120












          • I confused "Interval" and "Timeout" and updated the question, but your answer still seems to apply. Thank you. So, clearTimeout(myInterval) still applies to each iteration individually if in the loop, and doesn't get erased on the next iteration? Makes sense. Thank you.
            – auto
            Nov 14 '18 at 23:10


















          • I confused "Interval" and "Timeout" and updated the question, but your answer still seems to apply. Thank you. So, clearTimeout(myInterval) still applies to each iteration individually if in the loop, and doesn't get erased on the next iteration? Makes sense. Thank you.
            – auto
            Nov 14 '18 at 23:10
















          I confused "Interval" and "Timeout" and updated the question, but your answer still seems to apply. Thank you. So, clearTimeout(myInterval) still applies to each iteration individually if in the loop, and doesn't get erased on the next iteration? Makes sense. Thank you.
          – auto
          Nov 14 '18 at 23:10




          I confused "Interval" and "Timeout" and updated the question, but your answer still seems to apply. Thank you. So, clearTimeout(myInterval) still applies to each iteration individually if in the loop, and doesn't get erased on the next iteration? Makes sense. Thank you.
          – auto
          Nov 14 '18 at 23:10













          0














          Since setting a timeout actually returns a numerical ID of the timer, you can simply store/cache the timer associated with each element in a custom jQuery .data() object.



          Note that in the example below I have set the timer from your 200ms to 1000ms so that you can see the changes better.






          $('.my-elements').each(function(i) {
          var $thisElement = $(this);

          //add class every 2000 milliseconds
          setInterval(function() {

          $thisElement.addClass("active");
          var classRemovalTimer = setTimeout(function() {
          $thisElement.removeClass("active")
          }, 1000);

          // Store this class removal timer in jQuery data object
          $thisElement.data('class-removal-timer-id', classRemovalTimer);

          }, 2000);

          $thisElement.click(function() {
          // Check if timer exists for the element.
          // If it does, clear it
          var classRemovalTimer = $thisElement.data('class-removal-timer-id')
          if (classRemovalTimer) {
          window.clearTimeout(classRemovalTimer);
          }
          })

          })

          .active {
          background-color: red;
          color: white;
          }

          <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
          <div class="my-elements">1</div>
          <div class="my-elements">2</div>
          <div class="my-elements">3</div>
          <div class="my-elements">4</div>
          <div class="my-elements">5</div>





          Some additional pro-tips:




          • You are double wrapping your $(this) element, by first assigning it to thisElement and then wrapping $(thisElement) later. You only need to do that once

          • Read up about how you can take advantage of jQuery's .data() object/store






          share|improve this answer





















          • Okay. Interesting. I will try it. Thank you.
            – auto
            Nov 14 '18 at 23:21
















          0














          Since setting a timeout actually returns a numerical ID of the timer, you can simply store/cache the timer associated with each element in a custom jQuery .data() object.



          Note that in the example below I have set the timer from your 200ms to 1000ms so that you can see the changes better.






          $('.my-elements').each(function(i) {
          var $thisElement = $(this);

          //add class every 2000 milliseconds
          setInterval(function() {

          $thisElement.addClass("active");
          var classRemovalTimer = setTimeout(function() {
          $thisElement.removeClass("active")
          }, 1000);

          // Store this class removal timer in jQuery data object
          $thisElement.data('class-removal-timer-id', classRemovalTimer);

          }, 2000);

          $thisElement.click(function() {
          // Check if timer exists for the element.
          // If it does, clear it
          var classRemovalTimer = $thisElement.data('class-removal-timer-id')
          if (classRemovalTimer) {
          window.clearTimeout(classRemovalTimer);
          }
          })

          })

          .active {
          background-color: red;
          color: white;
          }

          <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
          <div class="my-elements">1</div>
          <div class="my-elements">2</div>
          <div class="my-elements">3</div>
          <div class="my-elements">4</div>
          <div class="my-elements">5</div>





          Some additional pro-tips:




          • You are double wrapping your $(this) element, by first assigning it to thisElement and then wrapping $(thisElement) later. You only need to do that once

          • Read up about how you can take advantage of jQuery's .data() object/store






          share|improve this answer





















          • Okay. Interesting. I will try it. Thank you.
            – auto
            Nov 14 '18 at 23:21














          0












          0








          0






          Since setting a timeout actually returns a numerical ID of the timer, you can simply store/cache the timer associated with each element in a custom jQuery .data() object.



          Note that in the example below I have set the timer from your 200ms to 1000ms so that you can see the changes better.






          $('.my-elements').each(function(i) {
          var $thisElement = $(this);

          //add class every 2000 milliseconds
          setInterval(function() {

          $thisElement.addClass("active");
          var classRemovalTimer = setTimeout(function() {
          $thisElement.removeClass("active")
          }, 1000);

          // Store this class removal timer in jQuery data object
          $thisElement.data('class-removal-timer-id', classRemovalTimer);

          }, 2000);

          $thisElement.click(function() {
          // Check if timer exists for the element.
          // If it does, clear it
          var classRemovalTimer = $thisElement.data('class-removal-timer-id')
          if (classRemovalTimer) {
          window.clearTimeout(classRemovalTimer);
          }
          })

          })

          .active {
          background-color: red;
          color: white;
          }

          <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
          <div class="my-elements">1</div>
          <div class="my-elements">2</div>
          <div class="my-elements">3</div>
          <div class="my-elements">4</div>
          <div class="my-elements">5</div>





          Some additional pro-tips:




          • You are double wrapping your $(this) element, by first assigning it to thisElement and then wrapping $(thisElement) later. You only need to do that once

          • Read up about how you can take advantage of jQuery's .data() object/store






          share|improve this answer












          Since setting a timeout actually returns a numerical ID of the timer, you can simply store/cache the timer associated with each element in a custom jQuery .data() object.



          Note that in the example below I have set the timer from your 200ms to 1000ms so that you can see the changes better.






          $('.my-elements').each(function(i) {
          var $thisElement = $(this);

          //add class every 2000 milliseconds
          setInterval(function() {

          $thisElement.addClass("active");
          var classRemovalTimer = setTimeout(function() {
          $thisElement.removeClass("active")
          }, 1000);

          // Store this class removal timer in jQuery data object
          $thisElement.data('class-removal-timer-id', classRemovalTimer);

          }, 2000);

          $thisElement.click(function() {
          // Check if timer exists for the element.
          // If it does, clear it
          var classRemovalTimer = $thisElement.data('class-removal-timer-id')
          if (classRemovalTimer) {
          window.clearTimeout(classRemovalTimer);
          }
          })

          })

          .active {
          background-color: red;
          color: white;
          }

          <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
          <div class="my-elements">1</div>
          <div class="my-elements">2</div>
          <div class="my-elements">3</div>
          <div class="my-elements">4</div>
          <div class="my-elements">5</div>





          Some additional pro-tips:




          • You are double wrapping your $(this) element, by first assigning it to thisElement and then wrapping $(thisElement) later. You only need to do that once

          • Read up about how you can take advantage of jQuery's .data() object/store






          $('.my-elements').each(function(i) {
          var $thisElement = $(this);

          //add class every 2000 milliseconds
          setInterval(function() {

          $thisElement.addClass("active");
          var classRemovalTimer = setTimeout(function() {
          $thisElement.removeClass("active")
          }, 1000);

          // Store this class removal timer in jQuery data object
          $thisElement.data('class-removal-timer-id', classRemovalTimer);

          }, 2000);

          $thisElement.click(function() {
          // Check if timer exists for the element.
          // If it does, clear it
          var classRemovalTimer = $thisElement.data('class-removal-timer-id')
          if (classRemovalTimer) {
          window.clearTimeout(classRemovalTimer);
          }
          })

          })

          .active {
          background-color: red;
          color: white;
          }

          <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
          <div class="my-elements">1</div>
          <div class="my-elements">2</div>
          <div class="my-elements">3</div>
          <div class="my-elements">4</div>
          <div class="my-elements">5</div>





          $('.my-elements').each(function(i) {
          var $thisElement = $(this);

          //add class every 2000 milliseconds
          setInterval(function() {

          $thisElement.addClass("active");
          var classRemovalTimer = setTimeout(function() {
          $thisElement.removeClass("active")
          }, 1000);

          // Store this class removal timer in jQuery data object
          $thisElement.data('class-removal-timer-id', classRemovalTimer);

          }, 2000);

          $thisElement.click(function() {
          // Check if timer exists for the element.
          // If it does, clear it
          var classRemovalTimer = $thisElement.data('class-removal-timer-id')
          if (classRemovalTimer) {
          window.clearTimeout(classRemovalTimer);
          }
          })

          })

          .active {
          background-color: red;
          color: white;
          }

          <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
          <div class="my-elements">1</div>
          <div class="my-elements">2</div>
          <div class="my-elements">3</div>
          <div class="my-elements">4</div>
          <div class="my-elements">5</div>






          share|improve this answer












          share|improve this answer



          share|improve this answer










          answered Nov 14 '18 at 23:08









          TerryTerry

          27.6k44167




          27.6k44167












          • Okay. Interesting. I will try it. Thank you.
            – auto
            Nov 14 '18 at 23:21


















          • Okay. Interesting. I will try it. Thank you.
            – auto
            Nov 14 '18 at 23:21
















          Okay. Interesting. I will try it. Thank you.
          – auto
          Nov 14 '18 at 23:21




          Okay. Interesting. I will try it. Thank you.
          – auto
          Nov 14 '18 at 23:21


















          draft saved

          draft discarded




















































          Thanks for contributing an answer to Stack Overflow!


          • Please be sure to answer the question. Provide details and share your research!

          But avoid



          • Asking for help, clarification, or responding to other answers.

          • Making statements based on opinion; back them up with references or personal experience.


          To learn more, see our tips on writing great answers.





          Some of your past answers have not been well-received, and you're in danger of being blocked from answering.


          Please pay close attention to the following guidance:


          • Please be sure to answer the question. Provide details and share your research!

          But avoid



          • Asking for help, clarification, or responding to other answers.

          • Making statements based on opinion; back them up with references or personal experience.


          To learn more, see our tips on writing great answers.




          draft saved


          draft discarded














          StackExchange.ready(
          function () {
          StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53310007%2fjavascript-adding-setinterval-dynamically-in-loop-and-clearing-each-instance%23new-answer', 'question_page');
          }
          );

          Post as a guest















          Required, but never shown





















































          Required, but never shown














          Required, but never shown












          Required, but never shown







          Required, but never shown

































          Required, but never shown














          Required, but never shown












          Required, but never shown







          Required, but never shown







          Popular posts from this blog

          How to pass form data using jquery Ajax to insert data in database?

          National Museum of Racing and Hall of Fame

          Guess what letter conforming each word