Skip to content Skip to sidebar Skip to footer

Stopping Dynamically Generated Setinterval

I am generating multiple charts each with their own setInterval to refresh the data. I have it set to clearInterval when the dynamically generated container is removed - but if I

Solution 1:

You can just use an object:

var myObj = {};

var location = "somevalue";

myObj[location] = setInterval(...

clearInterval(myObj[location]);

Solution 2:

ok - since I couldn't seem to wrap my head around some of your answers I decided to go low tech.

functiongenToken(){
    var num = Math.floor(Math.random() * 10000);
    var token = 't-' + num;
    return token;
}

functiongenLocation(){
    var chartToken = genToken();
    var newChart = '<div id="'+location+'" data-token="'+chartToken+'"></div>';
    $('#chartHome').append(newChart);
}

// inside my chart functionvar token = $('#'+location).data('token');
setInterval(function(){
    if( $('[data-token="'+token+'"]').length ){
        // still there - keep going
    }else{
        // all gone - time to stopclearInterval();
    }
},60000);

now when I do:

$('#'+location).remove();

the token also vanishes and won't be the same if I generate a new chart with the same location id.

Solution 3:

Stop using setInterval, use setTimeout instead (How do I execute a piece of code no more than every X minutes?):

functiongenerateChart(data, location) {

    var element = $('#'+location);

    var chart = newHighcharts.Chart({
        // blah blah blah
    }, foo);

    var foo = function() {

        if(element){

            // I'm doing stuff every minutesetTimeout(foo, 6000);
        }

    };

}

To stop it, just avoid the setTimeout or make element = null.

Maybe my code is a little bit wrong (I'm getting sleep right now), but the thing is to use setTimeout and closures.

If inside foo, something longs more than 6 seconds you will be in troubles since setTimeinterval will call it again, please watch http://www.youtube.com/watch?feature=player_detailpage&v=i_qE1iAmjFg#t=462s , so, this way you ensure that this will run 6 seconds after the last completed stuff.

I'll let this example here to posterity:

http://jsfiddle.net/coma/vECyv/2/

var closure = function(id) {

    var n = 0;
    var go = true;

    $('#' + id).one('click', function(event) {

        go = false;

    });

    var foo = function() {

        if(go) {

            console.log(id, n++);
            setTimeout(foo, 1000);

        }

    };

    foo();
};

closure('a');
closure('b');

Solution 4:

Not sure if anyone is still looking for this solution but I ran into this problem and chose the following approach.

For anyone dynamically creating private/anonymous intervals that need to be stopped based on some event. You can simply save the interval in a variable, then transfer that variable into a data property in your html element.

// Outer scopelet pos = 1let interval = setInterval(() => {
    if (pos < 700) {
      pos++;
    }
    htmlEl.style.top = pos + "px";
});

htmlEl.setAttribute("data-interval", interval)

This will save the numeric identifier of your interval, providing that html element is somewhere in your DOM.

Then, later you can simply extract this data attribute and use it to cancel an interval.

let intervalId = document.querySelector("#someElement").dataset.interval;
clearInterval(intervalId);

Post a Comment for "Stopping Dynamically Generated Setinterval"