0

I'm modifying A Better Simple Slideshow to have pausing capability. I've managed to separate pausing and unpausing out of autoCycle() into their own methods (pauseCycle and unpauseCycle), so I can use them for the pause control as well as autoCycle(). I've created the addPause() method to generate the pause control. The addPause() method successfully pauses the slideshow, but does something funky with the setInterval() or the interval var being passed to it when unpausing the slideshow. It appears to result in an additional setInterval() running simultaneously. Here's the code:

var aFSlides = function(el, options) {
  var $slideshows = document.querySelectorAll(el), // a collection of all of the slideshows
    $slideshow = {},
    Slideshow = {
      init: function(el, options) {
        this.counter = 0; // to keep track of current slide
        this.interval = 0; // to control autoCycle
        this.paused = 0; // to keep track of whether paused or not
        this.el = el; // current slideshow container
        this.$items = el.querySelectorAll('figure'); // a collection of all of the slides, caching for performance
        this.numItems = this.$items.length; // total number of slides
        options = options || {}; // if options object not passed in, then set to empty object 
        // options.auto = options.auto || false; // if options.auto object is not passed in, then set to false
        this.opts = {
          auto: (typeof options.auto === "undefined") ? false : options.auto,
          speed: (typeof options.speed === "undefined") ? 6000 : options.speed,
          pause: (typeof options.pause === "undefined") ? false : options.pause,
          pauseOnHover: (typeof options.pauseOnHover === "undefined") ? true : options.pauseOnHover,
        };
        this.$items[0].classList.add('current'); // add .current class to first figure
        if (this.opts.auto) {
          this.autoCycle(this.el, this.opts.speed, this.opts.pauseOnHover);
        }
        if (this.opts.pause) {
          this.addPause(this.el);
        }
      },
      showCurrent: function(i) {
        // increment or decrement this.counter depending on whether i === 1 or i === -1
        if (i > 0) {
          this.counter = (this.counter + 1 === this.numItems) ? 0 : this.counter + 1;
        } else {
          this.counter = (this.counter - 1 < 0) ? this.numItems - 1 : this.counter - 1;
        }
        // remove .show from whichever element currently has it 
        // http://stackoverflow.com/a/16053538/2006057
        [].forEach.call(this.$items, function(el) {
          el.classList.remove('current');
        });
        // add .show to the one item that's supposed to have it
        this.$items[this.counter].classList.add('current');
      },
      pauseCycle: function(el, speed) {
        var that = this;
        interval = clearInterval(interval);
        el.classList.add('paused');
      },
      unpauseCycle: function(el, speed) {
        var that = this;
        interval = window.setInterval(function() {
          that.showCurrent(1); // increment & show
        }, speed);
        el.classList.remove('paused');
      },
      addPause: function(el, speed) {
        var spanPause = document.createElement("span"),
          docFrag2 = document.createDocumentFragment(),
          that = this,
          thatSpeed = speed;
        spanPause.classList.add('pause');
        spanPause.innerHTML = 'Pause';
        docFrag2.appendChild(spanPause);
        el.appendChild(docFrag2);
        togglePause = function(el, speed) {
          if (that.paused == 1) {
            var speed = that.opts.speed;
            that.unpauseCycle(el, speed);
            that.paused = 0;
            return that.paused;
          } else if (that.paused == 0) {
            var speed = that.opts.speed;
            interval = clearInterval(interval);
            that.pauseCycle(el, speed);
            that.paused = 1;
            return that.paused;
          }
        }
        el.querySelector('.pause').addEventListener('click', function() {
          togglePause(el, speed);
        }, false);
      },
      autoCycle: function(el, speed, pauseOnHover) {
        var that = this;
        if (that.paused == 0) {
          that.unpauseCycle(el, speed);
        }
        if (pauseOnHover) {
          el.addEventListener('mouseover', function() {
            if (that.paused == 0) {
              that.pauseCycle(el, speed);
            }
          }, false);
          el.addEventListener('mouseout', function() {
            if (that.paused == 0) {
              that.unpauseCycle(el, speed);
            }
          }, false);
        } // end pauseonhover
      } // end autoCycle
    }; // end Slideshow object .....
  // make instances of Slideshow as needed
  [].forEach.call($slideshows, function(el) {
    $slideshow = Object.create(Slideshow);
    $slideshow.init(el, options);
  });
};

/* Init for this example snippet */

var aFS56c641d29d032 = {
  auto: true,
  speed: 2000,
  pause: true,
};
aFSlides('.aFS56c641d29d032', aFS56c641d29d032);
body {
  font: 400 10px/1.3 Menlo, Courier, sans-serif;
}
figure {
  display: none;
}
figure.current {
  display: block;
}
figure pre {
  font: 700 24px/1.3 Menlo, Courier, sans-serif;
  white-space: pre;
}
span {
  background: #f66;
  color: #fff;
  font: 700 16px/1.3 Menlo, Courier, sans-serif;
  padding: 10px 20px;
  display: inline-block;
}
<div id="smile-gallery" class="aFS56c641d29d032 ">
  <div class="slides">
    <figure class="slide" id="bna-1">
      <div class="slide-content">
        <pre>
 ________________________
|                        |
|                        |
|         0    0         |
|                        |
|       \________/       |
|                        |
|________________________|
</pre>
      </div>
    </figure>
    <figure class="slide" id="bna-2">
      <div class="slide-content">
        <pre>
 ________________________
|                        |
|                        |
|    o              O    |
|                        |
|                        |
|         ______/        |
|________________________|
</pre>
      </div>
    </figure>
    <figure class="slide" id="bna-3">
      <div class="slide-content">
        <pre>
 ________________________
|                        |
|                        |
|       ^       ^        |
|                        |
|                        |
|        (EEEEE)         |
|________________________|
</pre>
      </div>
    </figure>
    <figure class="slide" id="bna-4">
      <div class="slide-content">
        <pre>
 ________________________
|                        |
|                        |
|       |       |        |
|     ____________       |
|     \          /       |
|      \________/        |
|________________________|
</pre>
      </div>
    </figure>
  </div>
  <!-- /.slides  -->
</div>
<!-- /#smile-gallery -->
<p>
  Taken from <a href="https://github.com/leemark/better-simple-slideshow" target="_blank">A Better Simple Slideshow</a>.
</p>

As you run this script, if you play with the Pause control, some weird stuff happens. First it pauses and disables the pauseOnHover condition, like it should. Then you click it again, it unpauses and starts advancing two slides at a time. The pauseOnHover works again, but only pauses one of the slide advancements on hover, so the slideshow is still advancing one slide at a time. Click it Pause again and it stops advancing by two times, but it continues advancing at one slide at a time (when it should now be paused). Click is again and it begins advancing three frames at time (two if you're hovering over it again) and so on. Something just keeps getting added on every time and I can't figure out what it is. Please help.

Thanks!

UPDATE 22 Feb 2016

Here's a JSFiddle I've been working on for this project. Getting both pause AND pauseOnHover to work at the same time has been a nightmare.

Joe Rhoney
  • 353
  • 5
  • 14
  • 3
    I don't feel like reading your entire post but i noticed you are doing `interval = clearInterval(interval);` Seems wrong bcuz i'm pretty sure clearInterval doesn't return anything, so you may be overriding the actual intervalID returned from setInterval. – Eric Guan Feb 19 '16 at 03:35
  • Thank you for that. I thought that was strange myself, but I tried removing `interval =` and just leaving `clearInterval(interval);` in place and it produces exactly the same results. – Joe Rhoney Feb 19 '16 at 03:42
  • protip: `(function runthisperiodically() { try { all my code; setTimeout(runthisperiodically, ...); } catch(e) { console.error(e); }} ())` instead of setInterval. That way if your code breaks, it doesn't break every second until you go insane. `setTimeout` is your friend. `setInterval` is your crazy ex who keeps calling you even though you deleted their number and changed address. – Mike 'Pomax' Kamermans Feb 19 '16 at 03:47
  • Ok, I tried `setTimeout()` and I still got the same problem or similar problems. After looking into the difference between `setTimeout()` and `setInterval()`, I think I'm favoring `setTimeout()` for this project. So thank you for pointing that out. But it doesn't seem like my issue here has anything to do with either of those. – Joe Rhoney Feb 19 '16 at 22:28

2 Answers2

1

The interval variable needs to be tied to the proper scope (this). So where ever you reference the variable "interval" you need to prefix it with "this."

Search the code for "CHANGED" to see where I made changes.

var aFSlides = function(el, options) {
  var $slideshows = document.querySelectorAll(el), // a collection of all of the slideshows
    $slideshow = {},
    Slideshow = {
      init: function(el, options) {
        this.counter = 0; // to keep track of current slide
        this.interval = 0; // to control autoCycle
        this.paused = 0; // to keep track of whether paused or not
        this.el = el; // current slideshow container
        this.$items = el.querySelectorAll('figure'); // a collection of all of the slides, caching for performance
        this.numItems = this.$items.length; // total number of slides
        options = options || {}; // if options object not passed in, then set to empty object 
        // options.auto = options.auto || false; // if options.auto object is not passed in, then set to false
        this.opts = {
          auto: (typeof options.auto === "undefined") ? false : options.auto,
          speed: 300, // CHANGED: faster for development
          //speed: (typeof options.speed === "undefined") ? 6000 : options.speed,
          pause: (typeof options.pause === "undefined") ? false : options.pause,
          pauseOnHover: (typeof options.pauseOnHover === "undefined") ? true : options.pauseOnHover,
        };
        this.$items[0].classList.add('current'); // add .current class to first figure
        if (this.opts.auto) {
          this.autoCycle(this.el, this.opts.speed, this.opts.pauseOnHover);
        }
        if (this.opts.pause) {
          this.addPause(this.el);
        }
      },
      showCurrent: function(i) {
        // increment or decrement this.counter depending on whether i === 1 or i === -1
        if (i > 0) {
          this.counter = (this.counter + 1 === this.numItems) ? 0 : this.counter + 1;
        } else {
          this.counter = (this.counter - 1 < 0) ? this.numItems - 1 : this.counter - 1;
        }
        // remove .show from whichever element currently has it 
        // http://stackoverflow.com/a/16053538/2006057
        [].forEach.call(this.$items, function(el) {
          el.classList.remove('current');
        });
        // add .show to the one item that's supposed to have it
        this.$items[this.counter].classList.add('current');
      },
      pauseCycle: function(el, speed) {
        var that = this;
        clearInterval(this.interval); // CHANGED: clearInterval doesn't return anything usefull
        el.classList.add('paused');
      },
      unpauseCycle: function(el, speed) {
        var that = this;
        // CHANGED x2: 
  window.clearInterval(this.interval);
        this.interval = window.setInterval(function() {
          that.showCurrent(1); // increment & show
        }, speed);
        el.classList.remove('paused');
      },
      addPause: function(el, speed) {
        var spanPause = document.createElement("span"),
          docFrag2 = document.createDocumentFragment(),
          that = this,
          thatSpeed = speed;
        spanPause.classList.add('pause');
        spanPause.innerHTML = 'Pause';
        docFrag2.appendChild(spanPause);
        el.appendChild(docFrag2);
        togglePause = function(el, speed) {
     
          if (that.paused == 1) {
            var speed = that.opts.speed;
            that.unpauseCycle(el, speed);
            that.paused = 0;
            return that.paused;
          } else if (that.paused == 0) {
            var speed = that.opts.speed;
            // CHANGED
            clearInterval(that.interval);
            //interval = clearInterval(that.interval);
            that.pauseCycle(el, speed);
            that.paused = 1;
            return that.paused;
          }
        }
        el.querySelector('.pause').addEventListener('click', function() {
          togglePause(el, speed);
        }, false);
      },
      autoCycle: function(el, speed, pauseOnHover) {
        var that = this;
        if (that.paused == 0) {
          that.unpauseCycle(el, speed);
        }
        if (pauseOnHover) {
          el.addEventListener('mouseover', function() {
            if (that.paused == 0) {
              that.pauseCycle(el, speed);
            }
          }, false);
          el.addEventListener('mouseout', function() {
            if (that.paused == 0) {
              that.unpauseCycle(el, speed);
            }
          }, false);
        } // end pauseonhover
      } // end autoCycle
    }; // end Slideshow object .....
  // make instances of Slideshow as needed
  [].forEach.call($slideshows, function(el) {
    $slideshow = Object.create(Slideshow);
    $slideshow.init(el, options);
  });
};

/* Init for this example snippet */

var aFS56c641d29d032 = {
  auto: true,
  speed: 2000,
  pause: true,
};
aFSlides('.aFS56c641d29d032', aFS56c641d29d032);
body {
  font: 400 10px/1.3 Menlo, Courier, sans-serif;
}
figure {
  display: none;
}
figure.current {
  display: block;
}
figure pre {
  font: 700 24px/1.3 Menlo, Courier, sans-serif;
  white-space: pre;
}
span {
  background: #f66;
  color: #fff;
  font: 700 16px/1.3 Menlo, Courier, sans-serif;
  padding: 10px 20px;
  display: inline-block;
}
<div id="smile-gallery" class="aFS56c641d29d032 ">
  <div class="slides">
    <figure class="slide" id="bna-1">
      <div class="slide-content">
        <pre>
 ________________________
|                        |
|                        |
|         0    0         |
|                        |
|       \________/       |
|                        |
|________________________|
</pre>
      </div>
    </figure>
    <figure class="slide" id="bna-2">
      <div class="slide-content">
        <pre>
 ________________________
|                        |
|                        |
|    o              O    |
|                        |
|                        |
|         ______/        |
|________________________|
</pre>
      </div>
    </figure>
    <figure class="slide" id="bna-3">
      <div class="slide-content">
        <pre>
 ________________________
|                        |
|                        |
|       ^       ^        |
|                        |
|                        |
|        (EEEEE)         |
|________________________|
</pre>
      </div>
    </figure>
    <figure class="slide" id="bna-4">
      <div class="slide-content">
        <pre>
 ________________________
|                        |
|                        |
|       |       |        |
|     ____________       |
|     \          /       |
|      \________/        |
|________________________|
</pre>
      </div>
    </figure>
  </div>
  <!-- /.slides  -->
</div>
<!-- /#smile-gallery -->
<p>
  Taken from <a href="https://github.com/leemark/better-simple-slideshow" target="_blank">A Better Simple Slideshow</a>.
</p>
bob
  • 7,539
  • 2
  • 46
  • 42
  • This only works for the pauseOnHover feature. The pause control, doesn't work in your code. If you get it to work by adding `this.` to the `interval` in that method, we get the same results as before. I'm thinking the problem is perhaps that I need to use `this` because var `that` is a copy and therefore produces duplicate "runtime" or whatever. It's like it's starting a new setInterval and it adds another one every time you unpause the slideshow. But I can't figure out how to use `this` due to the scope within which I need to use it. – Joe Rhoney Feb 20 '16 at 01:30
  • I've updated the code to fix the this/that reference within the togglePause function. Search for CHANGED in the code. – bob Feb 21 '16 at 04:12
  • Yeah, I caught that myself as mentioned in my comment above. While we can make the Pause control work that way, we're still starting multiple `setInterval()`s somehow, and I think it's the confusing combination of `this` and `that` references. While we're using `that` (a copy) to start the `setInterval()` function, we're then using `this` (the original) to stop the 'setInterval()`, so it isn't stopping the one that is running. Click the Pause control a few times and you'll see what I mean. – Joe Rhoney Feb 22 '16 at 20:50
  • Nope. That's definitely not it. `that`, used the way it is in this script, where it is a variable representing `this`, effectively equals `this`. When changing the value of `that.something` to `1` for instance, `this.something` is also changed to `1`. So the problem I think lies somewhere else. Perhaps it's in my separation of functions, or the answer is getting lost in the complexity of _too many_ functions. I should have broken this question down more. – Joe Rhoney Feb 23 '16 at 18:37
  • Technically yes, mulitple INTERVALs are set, and there could be some leaks. I've updated the code, (find CHANGED x2) to clear the previous one before creating a new one. Yes, in the code the THIS and THAT are incredibly confusing, but would require a deep think-through to clean it up. – bob Feb 24 '16 at 02:33
  • Thanks! That works. Yeah, I did that "deep think-through" and clean up and found that you can use `that` and any such variable assigned to `this` and it affectively treats them the same. Also that multiple `setInterval()`s *were* running. Not only running simultaneously, but attached to the same variable. So any time you called that variable it would start another `setInterval()`. Thanks again for your help! – Joe Rhoney Feb 24 '16 at 18:23
  • You probably already know that THIS relates to scope. But if you're not comfy with THIS, I highly recommend getting a grip on it! https://toddmotto.com/everything-you-wanted-to-know-about-javascript-scope/ – bob Feb 25 '16 at 23:09
  • Yep. `this` is awesome. I use it a lot, but still get tripped up by it when trying to use it in a closure. – Joe Rhoney Feb 26 '16 at 18:15
0

I got it! Simple answer:

Stop multiplying it!

Solution #1: "Let it Run"

Don't stop setInterval(). Instead, give it some variables to check. If it returns false for any of them, don't execute the slide transition (or whatever it's supposed to execute in your case). setInterval() will still be running, checking for those variables every time it fires. But every time it fires the variables will return false and it will never execute the code inside. When a click occurs or something changes the variable(s), then when it fires again, it will execute the code inside (the slide transition, etc.). setInterval() never stops, so you never have to start it again and you never have to worry about how you're going to selecting the same instance of setInterval(). See example below:

var aFSlides = function (el, options) {
  var $slideshows = document.querySelectorAll(el), // a collection of all of the slideshow
  $slideshow = {},
  Slideshow = {
    init: function (el, options) {
      this.counter = 0; // to keep track of the current slide
      this.interval = 0; // to keep track of whether slideshow is running or not
      this.stopCycle = 0; // to keep track of whether the slideshow has been stopped or not
      this.hovered = 0; // to keep track of whether the mouse is hovering over the slideshow or not
      this.paused = 0; // to keep track of whether the pause control is set to "pause" or not
      this.el = el; // current slideshow container    
      this.$items = el.querySelectorAll('figure'); // a collection of all of the slides, caching for performance
      this.numItems = this.$items.length; // total number of slides
      options = options || {}; // if options object not passed in, then set to empty object 
      this.opts = {
        auto: (typeof options.auto === "undefined") ? false : options.auto,
        speed: (typeof options.speed === "undefined") ? 6000 : options.speed,
        pauseOnHover: (typeof options.pauseOnHover === "undefined") ? true : options.pauseOnHover,
        pause: (typeof options.pause === "undefined") ? false : options.pause,
      };
      this.$items[0].classList.add('current'); // add show class to first figure 
      if (this.opts.prevNext) {
        this.addPrevNext(this.el);
      }
      if (this.opts.pause) {
        this.addPause(this.el);
      }
      this.addEventListeners(this.el,this.opts.speed);
      if (this.opts.auto) {
        this.unpauseCycle(this.el, this.opts.speed, this.opts.pauseOnHover);
      }
      if (this.opts.fullScreen) {
        this.addFullScreen(this.el);
      }
      if (this.opts.swipe) {
        this.addSwipe(this.el);
      }
    },
    showCurrent: function (i) {
      // increment or decrement this.counter depending on whether i === 1 or i === -1
      if (i > 0) {
        this.counter = (this.counter + 1 === this.numItems) ? 0 : this.counter + 1;
      } else {
        this.counter = (this.counter - 1 < 0) ? this.numItems - 1 : this.counter - 1;
      }
      // remove .show from whichever element currently has it 
      // http://stackoverflow.com/a/16053538/2006057
      [].forEach.call(this.$items, function (el) {
        el.classList.remove('current');
      });
      // add .show to the one item that's supposed to have it
      this.$items[this.counter].classList.add('current');
    },
    addPause: function (el) {
      // build and inject prev/next controls
      // first create all the new elements
      var spanPause = document.createElement("span"),
      docFragPs = document.createDocumentFragment();
      // add classes
      spanPause.classList.add('pause');
      // add contents
      spanPause.innerHTML = 'Pause';
      // append elements to fragment, then append fragment to DOM
      docFragPs.appendChild(spanPause);
      el.appendChild(docFragPs);
    },
    unpauseCycle: function (el,speed) {
      var that = this;
      this.interval = setInterval(function () {
        if ((that.stopCycle != 1) && (that.hovered != 1)) {
          that.showCurrent(1); // increment & show
        }
      }, speed);
    },
    addEventListeners: function (el,speed,pauseOnHover) {
      var that = this;
      if (that.opts.pauseOnHover) {
        el.addEventListener('mouseover', function () {
          that.hovered = 1;
          return that.hovered;
        }, false);
        el.addEventListener('mouseout', function () {
          that.hovered = 0;
          return that.hovered;
        }, false);
      };
      el.querySelector('.pause').addEventListener('click', function () {
        if ((that.paused === 0) && (that.stopCycle != 1)) {
          that.stopCycle = 1;
          that.paused = 1;
          el.classList.add('paused');
          return that.stopCycle,that.paused;
        }
        else if ((that.paused === 1) || (that.stopCycle === 1)) {
          that.stopCycle = 0;
          that.paused = 0;
          el.classList.remove('paused');
          el.classList.remove('stopped');
          that.interval;
          return that.stopCycle,that.paused;
        }
      }, false);
    },
  }; // end Slideshow object .....
  // make instances of Slideshow as needed
  [].forEach.call($slideshows, function (el) {
    $slideshow = Object.create(Slideshow);
    $slideshow.init(el, options);
  });
};
var aFS56c641d29d032 = {
  auto: true,
  speed: 2000,
  prevNext: true,
  pause: true,
  swipe: true,
};
aFSlides('.aFS56c641d29d032', aFS56c641d29d032);
body {
    font: 400 14px/1.3 Menlo,Courier,sans-serif;
}
figure {
  display: none;
}
figure.current {
  display: block;
}
figure p {
  font: 700 24px/1.3 Menlo,Courier,sans-serif;
  white-space: pre;
}
span {
  font-weight: bold;
  padding: 10px;
  display: inline-block;
}
<body>
<div id="smile-gallery" class="aFS56c641d29d032 ">
        <div class="slides">
          <figure class="slide" id="bna-1">
            <div class="slide-content">
              <p>
 ________________________
|                        |
|                        |
|         0    0         |
|                        |
|       \________/       |
|                        |
|________________________|
</p></div>
          </figure>
          <figure class="slide" id="bna-2">
            <div class="slide-content">
              <p>
 ________________________
|                        |
|                        |
|    o              O    |
|                        |
|                        |
|         ______/        |
|________________________|
</p></div>
          </figure>
          <figure class="slide" id="bna-3">
            <div class="slide-content">
              <p>
 ________________________
|                        |
|                        |
|       ^       ^        |
|                        |
|                        |
|        (EEEEE)         |
|________________________|
</p></div>
          </figure>
          <figure class="slide" id="bna-4">
            <div class="slide-content">
              <p>
 ________________________
|                        |
|                        |
|       |       |        |
|     ____________       |
|     \          /       |
|      \________/        |
|________________________|
</p></div>
          </figure>
        </div><!-- /.slides  -->
      </div><!-- /#smile-gallery -->
<p>
Taken from <a href="https://github.com/leemark/better-simple-slideshow">A Better Simple Slideshow</a>.
</p>
</body>

Solution #2: "Don't Loose Track of it"

The idea here is to create variables for everything first, then use them, and always in the right scope (of course). So here's how to use them:

After you define variables (in the outer most scope of the object, for easier coding), assign your setInterval() to one of the variables (ex. myIntervalVar = setInterval( ... );), then always reference it with that variable. So to clear it, clearInterval(myIntervalVar). Make sure you're in the right scope, so you may need to use:

clearInterval(this.myIntervalVar)

or:

var equalThis = this;
someFunction(){
  clearInterval(equalThis.myIntervalVar);
}

Then any time you want to start/stop your setInterval(), check first if it's already running with a variable:

if (this.myRunningVar === 0) {
  this.myIntervalVar;
}

This of course means when you start setInterval() you need to set your variable to keep track of it too:

myIntervalVar = setInterval( function () {
  ...
  this.myRunningVar = 1;
  return myRunningVar;
}, false);

and:

if (this.myRunningVar === 0) {
  this.myIntervalVar;
  this.myRunningVar = 1;
  return myRunningVar;
}

and also whenever you stop it:

clearInterval(this.myIntervalVar)
this.myRunningVar = 0;
return myRunningVar;

This second solution could probably be elaborated on and should be more thoroughly tested. I went with the first solution because it was much easier and seemed cleaner to me.


Basically, the multiplying or stacking of setInterval()s firing simultaneously comes from running the function (or functions) that start it more than once without successfully stopping it. And even if you successfully stop it with clearInterval() it's still there (albeit nolonger firing). So if you have it assigned to a variable, all you need to do is call that variable and it will start again, picking up where it left off. Otherwise, if you newly try to define that variable again as a setInterval() function, say with a function you keep calling, instead of resetting the variable with a new setInterval() It just adds another setInterval() on to it:

startCycle(){
  myIntervalVar = setInterval( function () {
        // whatever you want to execute each time it fires
  }, false);
}

Calling startCycle() more than once will result in more than one setInterval()s running simultaneously, because each time you do, it adds setInterval() to myIntervalVar. And each time you set it or call the function that sets it, it not only adds your new setInterval(), is also plays all the old ones along with your new one. That is why I prefer to set and call it only once and use variables to govern whether is should actually execute the code inside each time it fires or it should just return false until one of those variables change. But supposing you cleared it with clearInterval() how do you get it started again? One key reason for assigning it to a variable is so you can call it again without adding another setInterval():

reStartCycle(){
  myIntervalVar;
}
Joe Rhoney
  • 353
  • 5
  • 14