重复函数内的变量保持旧值

时间:2013-08-20 09:26:59

标签: jquery

我是Jquery的新手,我似乎无法找到导致此问题的原因。

我有一个变量,每次函数GameStart()运行时都会得到一个新值,对于这个函数我试图创建一个暂停函数,在暂停函数中我有一个警告,它显示变量的值(只是作为现在的测试。)

问题是暂停点击事件不仅会提醒当前值,还会提醒所有以前的值。

这是什么原因?我该怎么做才能解决这个问题?

在小提琴示例中,按“开始”,然后按“暂停”,然后查看所有值。

JSFIDDLE:http://jsfiddle.net/Limitedmoves/SrWJP/

$(document).ready(function () {
    $('.butResize').click(function () {
        alert("hello"); 
            GameStart();    
    });

    function GameStart(){
        //Set needed random variables below
        var vSetTimer = 1000 * Math.floor(Math.random() * 10);
        var vBarWood = 1 + Math.floor(Math.random() * 400); 

        setTimeout(function () {
        //alert(vSetTimer);
            $('.div').animate({height: vBarWood }, 500);
        GameStart();    
    }, vSetTimer); //Time lenght set from vSetTime variable

    $('.pause').click(function () { //Start pause function
        var vTempTimer= vSetTimer;
        console.log(vTempTimer);    
    });
}
});

我已经在这里查看了stackoverflow并发现使用“return”解决了类似的行为,但是从我尝试过的内容中没有帮助。

事先谢谢! :)

3 个答案:

答案 0 :(得分:3)

每次调用GameStart时,都会向$('.pause')元素添加一个新的事件处理程序。

因此,当您第二次拨打GameStart时,点击.pause即可启动2个功能。

简单解决方案是unbind之前添加的所有点击处理程序,然后再添加新的点击处理程序:

$('.pause').unbind('click').click(function() {
    ...
});

修改 要获得更好更清洁的解决方案,请参阅@BjörnRobberg的回答

答案 1 :(得分:1)

@ ju-k的解释是正确的,并提供了一个有效的解决方案。但是,另一种解决方案可能如下所示:

$(document).ready(function () {

    $('.butResize').click(function () {
        alert("hello");
        GameStart();
    });

    var vSetTimer;
    var vBarWood;

    function GameStart(){
    //Set needed random variables below
        vSetTimer = 1000 * Math.floor(Math.random() * 10);
        vBarWood = 1 + Math.floor(Math.random() * 400);

        setTimeout(function () {

            //alert(vSetTimer);

            $('.div').animate({height: vBarWood }, 500);

            GameStart();    

        }, vSetTimer); //Time lenght set from vSetTime variable
    }

    $('.pause').click(function () { //Start pause function
        console.log(vSetTimer);
    });

});

即。将变量移动到外部作用域,这也可以解决它,而不必每次都取消绑定/绑定。

修改 正如评论中所指出的那样,没有解释为什么它在这个答案中的行为。这是:

问题中的行为原因如其他答案中所述,因为每次调用GameStart时,都会在与选择器“.pause”匹配的元素上附加一个点击处理程序。即第一次运行GameStart时,带有闭包var(vSetTimer)的处理程序被附加到“.pause”按钮。下次GameStart运行时,它会执行相同的操作,等等。此闭包不会改变,这就是为什么第一次出现的相同数字第二次显示,然后是下一个闭包var,依此类推。

答案 2 :(得分:0)

看看更新后的fiddle,我添加了一个明确的解决方案并解决了您的问题。

clearTimeout(timer);

我也将randNumber放在reSize()范围之外。