Tomek Buszewski
Tomek Buszewski

Reputation: 7955

clearInterval clearing two intervals

I can't run clearInterval for my functions. I use them to scroll the window by firing setInterval with function that fires scrollLeft. The code:

function scrollSpan() {
    $('nav#scrolling').children().css('width',config.windowWidth/10+'px');
    var inter;

    $('nav#scrolling').children('span').hover(function() {
        var value;

        if($(this).is('.scrollLeft')) {
            value = '-=50'
        } else {
            value = '+=50'
        }

        inter = setInterval(function() {
            $('body, html').animate({
                scrollLeft: value
            }, 50);
        },0)
    })

    $('nav#scrolling').children('span').mouseleave(function() {
        clearInterval(inter)
    })
}

Problem is, when mouseleave is triggered, interval doesn't stop.

Fiddle: http://jsfiddle.net/FpX4M/

Upvotes: 0

Views: 224

Answers (2)

James Montagne
James Montagne

Reputation: 78780

You are using hover where you should be using mouseenter. When only one handler is passed to hover that handler is called both on enter and leave. So your hover is called twice (once entering and once leaving) but your mouseleave is only called once. This is why even though one interval is cleared, the other remains.

See the documentation, in particular the signature added in v1.4 which takes only a single handler (scrolldown).

EDIT: Jsfiddles with proof:

http://jsfiddle.net/FpX4M/1/

Open your console and see that the handlers trigger twice and that interval continues.

http://jsfiddle.net/FpX4M/2/

In the console you will now see only one firing of the handler and then the intervals stop on leave.

Upvotes: 2

CodeMoose
CodeMoose

Reputation: 3025

Your whole scope is a little wonky. Try something like this:

var inter;

function scrollSpan() {
    $('nav#scrolling').children().css('width',config.windowWidth/10+'px');
}

$('nav#scrolling').children('span').hover(function() {
    var value;

    if($(this).is('.scrollLeft')) {
        value = '-=50'
    } else {
        value = '+=50'
    }

    inter = setInterval(function() {
        $('body, html').animate({
            scrollLeft: value
        }, 50);
    },0)
});

$('nav#scrolling').children('span').mouseleave(function() {
    clearInterval(inter)
});

You need to make sure the inter variable is accessible outside of the function. Also, generally, state functions shouldn't be assigned within functions unless you're changing them rapidly - and it doesn't look like you're detaching them anywhere. The only things that need to be in the function are things that will be repeated. Maybe add a clearInterval(inter); right before your inter = setInterval... to make sure no old intervals persist.

Upvotes: 0

Related Questions