Adam
Adam

Reputation: 832

jQuery - stop/ start a function

I've setup a fiddle here: http://jsfiddle.net/bd53ewoh/

When you hover over the ".homepage-modules" container is it possible to stop the "next" function so it stops cycling the active state and when you hover off the container the "next" function starts firing again? I'm a bit stumped at the moment and not sure of a way to do this

$('.homepage-modules div:first').addClass('active');

$.fn.cycle = function (timeout, cls) {
    var l = this.length,
        current = 0,
        prev = 0,
        elements = this;

    if (this.filter('.active').length > 0) {
        current = this.index(this.filter('.active')[0]) + 1;
        prev = current - 1;
    }

    function next() {
        elements.eq(prev).removeClass('active');
        elements.eq(current).addClass('active');
        prev = current;
        current = (current + 1) % l;
        setTimeout(next, timeout);
    }
    setTimeout(next, timeout);
    return this;
};

$('.homepage-modules div').cycle(2000, 'active');

Upvotes: 1

Views: 425

Answers (2)

Jamiec
Jamiec

Reputation: 136094

You should store the result of your setTimeout calls in a variable within your plugin. When the mouse is over your element you can use clearTimeout to stop the timer running, and when the mouse moves out you can start the timer again.

$.fn.cycle = function (timeout, cls) {
    var l = this.length,
        current = 0,
        prev = 0,
        elements = this,
        timerId;

    if (this.filter('.active').length > 0) {
        current = this.index(this.filter('.active')[0]) + 1;
        prev = current - 1;
    }

    this.parent().hover(function(){
        clearTimeout(timerId);    
    },
    function(){
        timerId = setTimeout(next, timeout);          
    })

    function next() {
        elements.eq(prev).removeClass('active');
        elements.eq(current).addClass('active');
        prev = current;
        current = (current + 1) % l;
        timerId = setTimeout(next, timeout);
    }
    timerId = setTimeout(next, timeout);
    return this;
};

Updated fiddle: http://jsfiddle.net/bd53ewoh/24/

Upvotes: 1

indextwo
indextwo

Reputation: 5915

You need a .hover() for your .homepage-modules div, and a simple boolean to handle the hover-state:

var noScrolling = false;

$('.homepage-modules').hover(
    function() {
        noScrolling = true;
    },

    function() {
        noScrolling = false;
        $('.homepage-modules div').cycle(2000, 'active');
    }
);

And then, within your next() function:

function next() {
    if (noScrolling) {
        console.log('I shouldn\'t be scrolling through.');
        return;
    }

    //  Otherwise, continue

Note that because I've thrown a return into your next() function, it actually returns out of the whole $fn.cycle parent function, hence why it's reinitialized when hovering out of the div.

I've updated your Fiddle here: http://jsfiddle.net/bd53ewoh/10/

Upvotes: 1

Related Questions