-->

Setinterval with exponential time decrease

2019-06-28 03:23发布

问题:

I've got a mousedown event with a setinterval. I want the time of intervals to be variable. So the first one is 500, the second one 500/2 = 250, etc. Any tips?

$plus.mousedown(function(e) {
    increment(20)
    timeout = setInterval(function(){
        increment(20)
    }, 500);
});
$(document).mouseup(function(){
    clearInterval(timeout);
    return false;
});

Cheers!

EDIT: sorry for the ambiguity. I want the time of interval to change during the mousedown. So while the mousedown is being performed the intervaltime should change. So not by every single mouse click but with every continuous click, and then reset it again.

回答1:

You can't really do this with setInterval() unless you keep clearing for a delay change, so you might as well write a wrapper around setTimeout() to accomplish something similar:

function easingTimeout(delay, fn)
{
  var id,
  invoker = function() {
    fn();
    delay = Math.floor(delay / 2);
    if (delay) {
      id = setTimeout(invoker, delay);
    } else {
      id = null;
    }
  }

  // start it off
  id = setTimeout(invoker, delay);

  return {
    clear: function() {
      if (id) {
        clearTimeout(id);
        id = null;
      }
    }
}

To use:

var timeout;

$plus.mousedown(function(e) {
    increment(20);
    timeout = easingTimeout(500, function() {
        increment(20);
    });
});

$(document).mouseup(function(){
    timeout.clear();
    return false;
});


回答2:

This solution does not depend on jQuery:

var timeoutInterval = 500;
var mousedown = false;

function incrementAndWait() {
  if (!mousedown) return;
  increment(20);
  timeout = setTimeout(incrementAndWait, timeoutInterval);
  timeoutInterval /= 2;
}

document.onmousedown = function() {
  timeoutInterval = 500; // Reset to 500 to allow multiple mousedown/mouseup
  mousedown = true;
  incrementAndWait();
};

document.onmouseup = function() {
  mousedown = false;
}

You can add console.log((new Date).getTime(), 20); to the incrementAndWait method to see the numbers going on the console. Something fun to play with :)