Javascript setTimeout / clearTimeout 问题

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/3015319/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-23 02:55:47  来源:igfitidea点击:

setTimeout / clearTimeout problems

javascriptjquerytimersettimeout

提问by Tillebeck

I try to make a page to go to the startpage after eg. 10sec of inactivity (user not clicking anywhere). I use jQuery for the rest but the set/clear in my test function are pure javascript.

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

In my frustation I ended up with something like this function that I hoped I could call on any click on the page. The timer starts fine, but is not reset on a click. If the function is called 5 times within the first 10 seconds, then 5 alerts will apear... no clearTimeout...

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

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

Any one got some lines of code that will do the trick? - on any click stop, reset and start the timer. - When timer hits eg. 10sec do something.

有没有人得到一些可以解决问题的代码行?- 在任何点击停止,重置并启动计时器。- 当定时器命中例如。10秒做某事。

回答by Pointy

You need to declare timeroutsidethe function. Otherwise, you get a brand new variable on each function invocation.

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

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

回答by CMS

The problem is that the timervariable is local, and its value is lost after each function call.

问题是timer变量是局部的,每次函数调用后它的值都会丢失。

You need to persist it, you can put it outside the function, or if you don't want to expose the variable as global, you can store it in a closure, e.g.:

你需要坚持它,你可以把它放在函数之外,或者如果你不想将变量公开为全局变量,你可以将它存储在一个闭包中,例如:

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

回答by arclight

That's because timer is a local variable to your function.

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

Try creating it outside of the function.

尝试在函数之外创建它。

回答by zero_cool

A way to use this in react:

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

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)
    })

  }
}

Helpful if you'd like to only call an API after the user has stopped typing for instance. The userTimeout function could be bound via onKeyUp to an input.

例如,如果您只想在用户停止输入后调用 API,则很有帮助。userTimeout 函数可以通过 onKeyUp 绑定到输入。

回答by clamiax

Not sure if this violates some good practice coding rule but I usually come out with this one:

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

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

This prevent the need to declare the timer out of the function.

这可以防止需要在函数之外声明定时器。

EDIT: this also don't declare a new variable at each invocation, but always recycle the same.

编辑:这也不在每次调用时声明一个新变量,而是始终回收相同的变量。

Hope this helps.

希望这可以帮助。

回答by Kino Bacaltos

This works well. It's a manager I've made to handle hold events. Has events for hold, and for when you let go.

这很好用。这是我用来处理保持事件的经理。有事件等待,以及当你放手。

function onUserHold(element, func, hold, clearfunc) {
    //var holdTime = 0;
    var holdTimeout;

    element.addEventListener('mousedown', function(e) {
        holdTimeout = setTimeout(function() {
            func();
            clearTimeout(holdTimeout);
            holdTime = 0;
        }, hold);
        //alert('UU');
    });

    element.addEventListener('mouseup', clearTime);
    element.addEventListener('mouseout', clearTime);

    function clearTime() {
        clearTimeout(holdTimeout);
        holdTime = 0;
        if(clearfunc) {
            clearfunc();
        }
    }
}

The element parameter is the one which you hold. The func parameter fires when it holds for a number of milliseconds specified by the parameter hold. The clearfunc param is optional and if it is given, it will get fired if the user lets go or leaves the element. You can also do some work-arounds to get the features you want. Enjoy! :)

element 参数是您持有的参数。func 参数在它保持由参数 hold 指定的毫秒数时触发。clearfunc 参数是可选的,如果给定它,如果用户放手或离开元素,它将被触发。您还可以通过一些变通方法来获得所需的功能。享受!:)

回答by Diego Favero

Practical example Using Jquery for a dropdown menu ! On mouse over on #IconLoggedinUxExternal shows div#ExternalMenuLogin and set time out to hide the div#ExternalMenuLogin

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

On mouse over on div#ExternalMenuLogin it cancels the timeout. On mouse out on div#ExternalMenuLogin it sets the timeout.

将鼠标悬停在 div#ExternalMenuLogin 上时,它会取消超时。在 div#ExternalMenuLogin 上鼠标移出时,它会设置超时。

The point here is always to invoke clearTimeout before set the timeout, as so, avoiding double calls

这里的重点总是在设置超时之前调用 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
    );
});