Joshua Joshua - 2 months ago 10
Javascript Question

I'm having issues with clearTimeout() on a quotes rotator

I'm using this Codrops Blueprint to create a quotes rotator. I modified the rotator to have a next button, powered by the code below:

_startRotator: function() {

if (this.support) {
this._startProgress();
}

var timeout = setTimeout($.proxy(function() {
if (this.support) {
this._resetProgress();
}
this._next();
this._startRotator();
}, this), this.options.interval);

$(".testimonial-next").click($.proxy(function() {
clearTimeout(timeout);
if (this.support) {
this._resetProgress();
}
this._next();
this._startRotator();

}, this));
},


I added the .click function below the setTimeout function, and added the var to the setTimeout function.

When .testimonial-next is clicked, the rotator's timer is reset and the code in the timer is instantly executed. As far as I can tell, the timer restarts itself, so I shouldn't have to add code to do this.

On the website where this is put to use (see the "Testimonials" section), however, there seems to be a problem. There should be five quotes, in the order of Kim, Lynn, Shannon, Jennifer, and Chris. If the timer runs without being interrupted, everything works as expected. If the Next button is clicked, certain quotes seem to be skipped. Other times, the quotes stop rotating or randomly rotate at a high speed.

What am I doing wrong?

Answer

Your button click handler is attached again and again to the button, making a click result in several executions of the same code.

To solve this you can best move that piece of code out of the _startRotator function and move it somewhere where it will only be executed once.

That way, when you click, there will be only one handler that gets executed.

Less nice, but also a solution, would be to keep the code where it is, but always first remove any existing click handler, before you attach it again:

    $(".testimonial-next").off('click').on('click', $.proxy(function() {
        // etc...

But this is really an ugly solution. Try to move the code.