1

我正在生成多个图表,每个图表都有自己的 setInterval 来刷新数据。当动态生成的容器被删除时,我将它设置为 clearInterval - 但是如果我重新加载并且它具有相同的 id,旧的 setInterval 将继续运行。有没有办法设置一个动态命名的 setInterval 可以在生成替换时停止?

现在我正在使用:

function generateChart(data, location){
    var chart = new Highcharts.Chart({
        // blah blah blah
    }, function(chart){
        setInterval(function(){
            if($('#'+location).length){
                // I'm doing stuff every minute
            }else{
                clearInterval();
            }
        },60000);
    });
}

发生的情况是,该位置是一个随机生成的字符串,它成为 Highchart 容器的元素 ID,如果用户保存图表,它就成为唯一标识符。如果用户更新已保存的图表并重新加载图表,则旧图表将获得 .removed() 并在其位置生成新图表。现在,新的与旧的具有相同的元素 ID,并且由于旧的间隔找到了它想要它尝试继续更新的容器——这是因为它的图表失败了。

有没有办法设置我可以用于 setInterval 的动态变量,以便我可以对其进行 clearInterval ?

var blob+location = setInterval(function(){ ...

接着

clearInterval(blob+location);
4

4 回答 4

3

您可以只使用一个对象:

var myObj = {};

var location = "somevalue";

myObj[location] = setInterval(...

clearInterval(myObj[location]);
于 2013-05-13T22:31:26.700 回答
0

好的 - 因为我似乎无法理解你的一些答案,所以我决定采用低技术。

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

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

// inside my chart function

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

现在当我这样做时:

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

如果我生成具有相同位置 ID 的新图表,令牌也会消失并且不会相同。

于 2013-05-13T23:28:20.137 回答
0

停止使用 setInterval,改用 setTimeout(如何不超过每 X 分钟执行一段代码?):

function generateChart(data, location) {

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

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

    var foo = function() {

        if(element){

            // I'm doing stuff every minute

            setTimeout(foo, 6000);
        }

    };

}

要停止它,只需避免 setTimeout 或 make element = null

也许我的代码有点错误(我现在正在睡觉),但问题是使用 setTimeout 和闭包。

如果在 foo 中,有些东西超过 6 秒,你会遇到麻烦,因为 setTimeinterval 会再次调用它,请观看http://www.youtube.com/watch?feature=player_detailpage&v=i_qE1iAmjFg#t=462s,所以,这样您确保这将在最后完成的内容后 6 秒运行。

我将把这个例子留给后代:

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');
于 2013-05-13T22:34:24.617 回答
0

不确定是否有人仍在寻找此解决方案,但我遇到了这个问题并选择了以下方法。

对于任何动态创建需要根据某些事件停止的私有/匿名间隔的人。您可以简单地将间隔保存在变量中,然后将该变量传输到 html 元素中的数据属性中。

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

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

这将保存间隔的数字标识符,前提是 html 元素位于 DOM 中的某个位置。

然后,稍后您可以简单地提取此数据属性并使用它来取消间隔。

let intervalId = document.querySelector("#someElement").dataset.interval;
clearInterval(intervalId);
于 2021-08-05T03:11:22.307 回答