2010-06-10 97 views
78

我尝试让页面进入首页后,例如。 10秒的不活动(用户不在任何地方点击)。我使用其余的jQuery,但在我的测试函数中设置/清除纯JavaScript。setTimeout/clearTimeout问题

在我的沮丧中,我最终得到了类似这个函数的东西,我希望我可以在页面上点击任何东西。计时器可以正常启动,但不会在点击时重置。如果该函数的第一个10秒内调用5次,然后5个警报将apear ...没有... clearTimeout

function endAndStartTimer() { 
    window.clearTimeout(timer); 
    var timer; 
    //var millisecBeforeRedirect = 10000; 
    timer = window.setTimeout(function(){alert('Hello!');},10000); 
} 

任何一个得到了一些代码行,将这样的伎俩? - 任何点击停止,重置并启动计时器。 - 当定时器命中例如。 10秒做一些事情。

回答

177

您需要声明“定时器”以外的的功能。否则,每个函数调用都会得到一个全新的变量。

var timer; 
function endAndStartTimer() { 
    window.clearTimeout(timer); 
    //var millisecBeforeRedirect = 10000; 
    timer = window.setTimeout(function(){alert('Hello!');},10000); 
} 
+4

谢谢你救了我一个小时! – 2016-12-29 08:55:16

14

这是因为计时器是您的函数的局部变量。

尝试在函数之外创建它。

43

问题是timer变量是本地的,并且在每次函数调用后它的值都会丢失。

你需要坚持它,你可以把它的功能之外,或者如果你不想暴露变量,全局的,你可以将其存储在一个closure,如:

var endAndStartTimer = (function() { 
    var timer; // variable persisted here 
    return function() { 
    window.clearTimeout(timer); 
    //var millisecBeforeRedirect = 10000; 
    timer = window.setTimeout(function(){alert('Hello!');},10000); 
    }; 
})(); 
3

不知道这是否违反了一些好的做法编码规则,但我通常用这一个站出来:

if(typeof __t == 'undefined') 
     __t = 0; 
clearTimeout(__t); 
__t = setTimeout(callback, 1000); 

这防止需要申报定时器中断的功能。

编辑:这也不要在每次调用时声明一个新的变量,但总是重复使用。

希望这会有所帮助。

2

使用这种的方式作出反应:

class Timeout extends Component { 
    constructor(props){ 
    super(props) 

    this.state = { 
     timeout: null 
    } 

    } 

    userTimeout(){ 
    const { timeout } = this.state; 
    clearTimeout(timeout); 
    this.setState({ 
     timeout: setTimeout(() => {this.callAPI()}, 250) 
    }) 

    } 
} 

有用的,如果你想在用户键入停止例如后只调用的API。 userTimeout函数可以通过onKeyUp绑定到输入。

+1

这是我一直在寻找几个小时,谢谢。我只是想知道是否有更好的方法来实现这种结果? – nikasv 2017-11-26 10:33:10

+1

@nikasv遏制和debouncing是两种选择:https://medium.com/@jh3y/throttling-and-debouncing-in-javascript-b01cad5c8edf – 2017-11-26 18:30:44

+1

不知道如何实现这一点起到了不参与工作机会的一部分 - 因此了解这种方法被认为是基本的。 – 2017-11-26 18:31:39