sgkdnay
sgkdnay

Reputation: 327

$.each & setTimeOut Issue - TimeOut isn't clearing

var TimeOut; //Global
$('[name^="HMapDot"]').each(function(i){
    TimeOut = setTimeout(function(){
        $('[name^="HMapDot"]').css({'visibility':'hidden'});
        $('#HMapTime').html($('[name="HMapDot'+i+'"]').attr('role')+' [ '+(i+1)+' ]');
        $('[name="HMapDot'+i+'"]').css({'visibility':'visible'});
    },i * iTime);
    if(i == (iMany-1) || $('[name^="HMapDot"]').length == 0){ clearTimeout(TimeOut); return false; }
});

I have this code working just fine, using JQuery 2.x and AJAX to pull data. My intention was to delay the dot on the "map" to appear/disappear every second (slider values). Now when I click on "Stop", the page, values, element will be $.remove, but the timer will continued to be counted down. How do I stop the timer and $.each?

Modified code below that works:

var TimeOuts = []; //Global
var T;
function ClearTimeOuts(){
    for(var i in TimeOuts){
        clearTimeout(TimeOuts[i]);
    }
}
$('[name^="HMapDot"]').each(function(i){
    T = setTimeout(function(){
        $('[name^="HMapDot"]').css({'visibility':'hidden'});
        $('#HMapTime').html($('[name="HMapDot'+i+'"]').attr('role')+' [ '+(i+1)+' ]');
        $('[name="HMapDot'+i+'"]').css({'visibility':'visible'});
        if(i == (iMany-1) || $('[name^="HMapDot"]').length == 0){ 
            ClearTimeOuts(); 
            return false;
        }
    },i * iTime);
    TimeOuts.push(T);
});

Upvotes: 0

Views: 72

Answers (2)

Shimon Rachlenko
Shimon Rachlenko

Reputation: 5517

You are calling the setTimeout inside of each - you need an array to store and stop timeout handles:

var TimeOuts = []; //Global
function ClearTimeOuts(){
    for(var i in TimeOuts){
        clearTimeout(TimeOuts[i]);
    }
}
$('[name^="HMapDot"]').each(function(i){
    var T = setTimeout(function(){
        $('[name^="HMapDot"]').css({'visibility':'hidden'});
        $('#HMapTime').html($('[name="HMapDot'+i+'"]').attr('role')+' [ '+(i+1)+' ]');
        $('[name="HMapDot'+i+'"]').css({'visibility':'visible'});
    },i * iTime);
    if(i == (iMany-1) || $('[name^="HMapDot"]').length == 0){ 
        ClearTimeOuts(); 
        return false;
    }
    TimeOuts.push(T);
});

Upvotes: 2

Guffa
Guffa

Reputation: 700192

All your dots share the same variable for keeping track of the timer, so each one will overwrite the previous. You need one variable for each dot.

Declare the variable inside the function, that will create a local variable for each dot:

$('[name^="HMapDot"]').each(function(i){
    var TimeOut;
    TimeOut = setTimeout(function(){
        $('[name^="HMapDot"]').css({'visibility':'hidden'});
        $('#HMapTime').html($('[name="HMapDot'+i+'"]').attr('role')+' [ '+(i+1)+' ]');
        $('[name="HMapDot'+i+'"]').css({'visibility':'visible'});
    },i * iTime);
    if(i == (iMany-1) || $('[name^="HMapDot"]').length == 0){ clearTimeout(TimeOut); return false; }
});

Upvotes: 0

Related Questions