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.