clearInterval未设置

时间:2014-01-02 22:04:12

标签: javascript ajax

我正在尝试创建一个将切换setInterval / clearInterval的按钮。 setInterval将正常运行,但是再次单击该按钮时,不会执行clearInterval。这是一个可变范围问题还是设置函数的问题?

http://jsfiddle.net/BxLps/1/

$(function () {
    var int;
    var onrepeat;

    $('button[id^=temp]').click(function () {
        window.id = $(this).attr("value");
        var int = setInterval(doAjax, 3000);

        if (onrepeat == false) {
            $(this).find('i').addClass("fa-spin");
            doAjax();
            int;
            onrepeat = true;
        } else {
            clearInterval(int);
            $(this).find('i').addClass("fa-spin");
            onrepeat = false;
        }
    });
});
function doAjax() {
    $.ajax({
        type: "GET",
        url: "ajax.php",
        data: "a=cur-temp&id=" + id,
        success: function (msg) {
            $("#cur-temp").html(msg);
        }
    })
};

4 个答案:

答案 0 :(得分:2)

  

这是一个可变范围问题吗?

是。您已经使用了var int两次,第二次引入了一个局部变量,您确实希望访问外部变量。

但是,对于具有该选择器的所有元素,使用单个int变量仍然可能会出现问题。我现在创建了一个对象,它在对象上存储元素的每个id的interval ID,你也可以使用each循环为每个元素创建一个额外的变量。

此外,您的全局变量id非常糟糕,最好使用doAjax函数的参数。

$(function () {
    var ints = {};

    $('button[id^=temp]').click(function () {
        var id = $(this).attr("value");

        if (id in ints) {
            $(this).find('i').removeClass("fa-spin");
            clearInterval(ints[id]);
            delete ints[id];
        } else {
            $(this).find('i').addClass("fa-spin");
            doAjax(id);
            ints[id] = setInterval(function() {
                doAjax(id);
            }, 3000);
        }
    });
});

答案 1 :(得分:0)

只需删除int的第二个声明。

$(function () {

    var int;
    $('button[id^=temp]').click(function () {
        window.id = $(this).attr("value");
        int = setInterval(doAjax, 3000); //remove var to prevent new declaration

        if (onrepeat == false) {
            $(this).find('i').addClass("fa-spin");
            doAjax();
            int;
            onrepeat = true;
        } else {
            clearInterval(int);
            $(this).find('i').addClass("fa-spin");
            onrepeat = false;
        }
    });
});

JS小提琴: http://jsfiddle.net/9tkU2/

答案 2 :(得分:0)

真正的问题是它每次都在创造新的间隔。想一想,每次“点击”都会运行该代码(因此它正在执行setInterval)。

解决方案是在点击之外声明一次(并且仅一次)。然后在条件

中移动setInterval
var int;
var onrepeat;

$('button[id^=temp]').click(function () {
    window.id = $(this).attr("value");

    if (onrepeat == false) {
        $(this).find('i').addClass("fa-spin");
        doAjax();
        int = setInterval(doAjax, 3000);
        onrepeat = true;
    } else {
        clearInterval(int);
        $(this).find('i').addClass("fa-spin");
        onrepeat = false;
    }
});

答案 3 :(得分:0)

您的问题是变量int的范围。您正在函数内部声明它,并且在您认为正在清除间隔时,原来的变量int已被破坏。

因此只需从函数内部的var int =...中删除var

如果问题仍然存在,请继续阅读下面的内容。

好吧,我经历了同样的问题太多次了,通常我会顺其自然, 但是大多数时候,我意识到清除间隔后间隔会继续运行,这可能会影响设备的性能(就像有一个无限循环)。

所以我做了一些研究,发现了问题所在,然后编写了简单的代码来解决它。

现在,在大多数情况下,当您启动一个间隔(很可能是由事件触发)时,便会声明该间隔的多个实例(无论出于何种原因)...

因此,当您以后清除间隔时,仅清除* top-level间隔,然后设置下一个级别间隔。 (顶层可能不是正确的单词)

为了真正清除间隔,我使用了以下方法:

设置时间间隔:

if(!timer)   
    timer =setInterval(myFunction, 1000);

清除间隔:

clearInterval(timer);
timer=null;
while (timer!== null){
    timer=null;
}

您可能决定清除while循环内的时间间隔,但是我发现这对我有用,并且比之有效。

确保检查间隔变量的范围(在上述情况下为计时器)