admin管理员组

文章数量:1134248

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.

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...

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.

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.

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...

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.

Share Improve this question edited Jul 8, 2013 at 5:03 Mark Fox 8,9249 gold badges56 silver badges77 bronze badges asked Jun 10, 2010 at 14:26 TillebeckTillebeck 3,5238 gold badges45 silver badges63 bronze badges
Add a comment  | 

8 Answers 8

Reset to default 273

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

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

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

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

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

Try creating it outside of the function.

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.

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.

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

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

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

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

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! :)

<!DOCTYPE html>
<html>

<body>

  <h2>EJEMPLO CONOMETRO CANCELABLE</h2>

  <button onclick="inicioStart()">INICIO</button>
  <input type="text" id="demostracion">
  <button onclick="finStop()">FIN</button>

  <script>
    let cuenta = 0;
    let temporalTiempo;
    let statusTime = false;


    function cronometro() {
      document.getElementById("demostracion").value = cuenta;
      cuenta++;
      temporalTiempo = setTimeout(cronometro, 500);
    }

    function inicioStart() {
      if (!Boolean(statusTime)) {
        statusTime = true;
        cronometro();
      }
    }

    function finStop() {
      clearTimeout(temporalTiempo);
      statusTime = false;

    }
  </script>

</body>

</html>

本文标签: javascriptsetTimeoutclearTimeout problemsStack Overflow