setTimeout / clearTimeout问题

时间:2010-06-10 14:26:50

标签: javascript jquery timer settimeout

我试图让页面在例如之后转到起始页面。 10秒不活动(用户不点击任何地方)。我在其余部分使用jQuery,但我的测试函数中的set / clear是纯javascript。

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

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

任何人都有一些代码可以解决问题吗?   - 在任何单击停止时,重置并启动计时器。   - 当计时器击中时,例如。 10秒做某事。

7 个答案:

答案 0 :(得分:195)

您需要在函数外声明timer 。否则,您将在每个函数调用中获得一个全新的变量。

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

答案 1 :(得分:44)

问题是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); 
  };
})();

答案 2 :(得分:14)

那是因为timer是你函数的局部变量。

尝试在功能之外创建它。

答案 3 :(得分:3)

一种在反应中使用它的方法:

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绑定到输入。

答案 4 :(得分:2)

不确定这是否违反了一些良好的练习编码规则,但我通常会提出这个规则:

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

这可以防止需要将定时器声明为函数。

编辑:这也不会在每次调用时声明一个新变量,但总是会循环使用它。

希望这有帮助。

答案 5 :(得分:0)

这很好。我是负责处理保持事件的经理。有要保留的事件以及您放手的事件。

async theMethod() {
  smallArray = await module(param);
  bigArray.push(smallArray);
}

元素参数是您持有的那个。当func参数保持由参数hold指定的毫秒数时,它将触发。 clearfunc参数是可选的,如果指定了该参数,则如果用户放开或离开该元素,它将被触发。您也可以采取一些变通方法来获得所需的功能。请享用! :)

答案 6 :(得分:0)

实际示例使用Jquery下拉菜单! 将鼠标悬停在#IconLoggedinUxExternal上会显示div#ExternalMenuLogin并设置超时以隐藏div#ExternalMenuLogin

将鼠标悬停在div#ExternalMenuLogin上可取消超时。 在div#ExternalMenuLogin上单击鼠标时,将设置超时。

这里的重点始终是在设置超时之前调用clearTimeout,这样可以避免重复调用

var ExternalMenuLoginTO;
$('#IconLoggedinUxExternal').on('mouseover mouseenter', function () {

    clearTimeout( ExternalMenuLoginTO )
    $("#ExternalMenuLogin").show()
});

$('#IconLoggedinUxExternal').on('mouseleave mouseout', function () {

    clearTimeout( ExternalMenuLoginTO )    
    ExternalMenuLoginTO = setTimeout(
        function () {

            $("#ExternalMenuLogin").hide()

        }
        ,1000
    );
    $("#ExternalMenuLogin").show()
});

$('#ExternalMenuLogin').on('mouseover mouseenter', function () {

    clearTimeout( ExternalMenuLoginTO )
});
$('#ExternalMenuLogin').on('mouseleave mouseout', function () {

    clearTimeout( ExternalMenuLoginTO )
    ExternalMenuLoginTO = setTimeout(
        function () {

            $("#ExternalMenuLogin").hide()

        }
        ,500
    );
});