jquery 在输入更改时扩展 setTimeout 函数

jquery extend a setTimeout function on input change

我正在尝试为通过单独的 .on('click') 函数启动的 setTimeout() 添加额外的时间。

请按照我的代码描述了解发生了什么

// my control opacity jQuery object
var $controlOpacity = $('#control-opacity');

// when the child button is clicked it reveals my input range slider
$controlOpacity.on('click','BUTTON', function() {

    // this toggles a open class to reveal my input range slider
    $controlOpacity.toggleClass('open');

    // begin the 5 second set timeout function 
    setTimeout(function(){

        // removes the open class to hide my input range slider
        $controlOpacity.removeClass('open');

    }, 5000);

});

// my input range slider inside my control opacity div
$('INPUT', $controlOpacity).change(function() {

    // how can I add another 5 seconds to setTimeout function via this function?

});

因此,当我的输入更改函数触发时,我希望能够通过 .on('click') 函数 [=16] 将当前 运行 的 setTimeout 函数再增加 5 秒=]

我确定有一个明显的方法可以做到这一点,但是最干净的 jQuery 解决方案是什么?

谢谢

您无法更改正在进行的 setTimeout 的超时 - 相反,您必须明确 clearTimeout 现有超时,然后使用新的超时再次调用 setTimeout期间。为此,您需要一个持久变量,用于记录下一次超时(如果有)何时触发,否则为 0 - 当第二个侦听器触发时,检查该变量与 Date.now() 之间的差异以找出新超时需要持续多长时间:

const removeFn = () => {
  $controlOpacity.removeClass('open');
  triggerAt = 0;
};
let timeout;
let triggerAt = 0;

$controlOpacity.on('click','BUTTON', function() {
  $controlOpacity.toggleClass('open');
  timeout = setTimeout(removeFn, 5000);
  // Set triggerAt so we can determine how long the timeout has left later
  triggerAt = Date.now() + 5000;
});

$('INPUT', $controlOpacity).change(function() {
  // Clear the existing timeout, if it exists
  clearTimeout(timeout);
  // If no timeout is running, return early
  if (!triggerAt) return;
  // Figure out how much time was remaining on the existing timeout
  const remaining = triggerAt - Date.now();
  // Set the new timeout for 5000 ms plus however long the old timeout had left
  timeout = setTimeout(removeFn, remaining + 5000);
  triggerAt += 5000;
});

ES5 版本:

var removeFn = function() {
  $controlOpacity.removeClass('open');
  triggerAt = 0;
};
var timeout;
var triggerAt = 0;

$controlOpacity.on('click','BUTTON', function() {
  $controlOpacity.toggleClass('open');
  timeout = setTimeout(removeFn, 5000);
  // Set triggerAt so we can determine how long the timeout has left later
  triggerAt = Date.now() + 5000;
});

$('INPUT', $controlOpacity).change(function() {
  // Clear the existing timeout, if it exists
  clearTimeout(timeout);
  // If no timeout is running, return early
  if (!triggerAt) return;
  // Figure out how much time was remaining on the existing timeout
  var remaining = triggerAt - Date.now();
  // Set the new timeout for 5000 ms plus however long the old timeout had left
  timeout = setTimeout(removeFn, remaining + 5000);
  triggerAt += 5000;
});

正如您的问题所问,这 将现有超时延长 5000 毫秒 - 一种替代方法,它只是 清除 现有超时并设置未来 5000 毫秒的新超时将减少代码,因为您只需要跟踪 是否 超时正在进行,而不是还剩多少时间:

const removeFn = () => {
  $controlOpacity.removeClass('open');
  running = false;
};
let timeout;
let running = false;

$controlOpacity.on('click','BUTTON', function() {
  $controlOpacity.toggleClass('open');
  timeout = setTimeout(removeFn, 5000);
  running = true;
});
$('INPUT', $controlOpacity).change(function() {
  clearTimeout(timeout);
  if (!running) return;
  timeout = setTimeout(removeFn, 5000);
});

ES5 版本:

var removeFn = function() {
  $controlOpacity.removeClass('open');
  running = false;
};
var timeout;
var running = false;

$controlOpacity.on('click','BUTTON', function() {
  $controlOpacity.toggleClass('open');
  timeout = setTimeout(removeFn, 5000);
  running = true;
});
$('INPUT', $controlOpacity).change(function() {
  clearTimeout(timeout);
  if (!running) return;
  timeout = setTimeout(removeFn, 5000);
});

如果 open class 不存在时无法触发 change 事件,那么它就更容易了,因为不需要检查是否超时是否为运行:

const removeFn = () => {
  $controlOpacity.removeClass('open');
};
let timeout;
$controlOpacity.on('click','BUTTON', function() {
  $controlOpacity.toggleClass('open');
  timeout = setTimeout(removeFn, 5000);
});
$('INPUT', $controlOpacity).change(function() {
  clearTimeout(timeout);
  timeout = setTimeout(removeFn, 5000);
});

ES5 版本:

var removeFn = function() {
  $controlOpacity.removeClass('open');
};
var timeout;
$controlOpacity.on('click','BUTTON', function() {
  $controlOpacity.toggleClass('open');
  timeout = setTimeout(removeFn, 5000);
});
$('INPUT', $controlOpacity).change(function() {
  clearTimeout(timeout);
  timeout = setTimeout(removeFn, 5000);
});

对 CertainPerformance 的类似回答,但我会考虑制作一个函数来为您处理计时器的清除和设置。本质上,要点是一样的——你不能给计时器加时间。您必须清除计时器并重新启动一个新计时器。

// my control opacity jQuery object
var $controlOpacity = $('#control-opacity');
var removeOpacityTimer;

function removeOpacity() {
    clearTimeout(removeOpacityTimer);

    // begin the 5 second set timeout function 
    removeOpacityTimer = setTimeout(function(){

        // removes the open class to hide my input range slider
        $controlOpacity.removeClass('open');

    }, 5000);
}

// when the child button is clicked it reveals my input range slider
$controlOpacity.on('click','BUTTON', function() {

    // this toggles a open class to reveal my input range slider
    $controlOpacity.toggleClass('open');

    removeOpacity();
});

// my input range slider inside my control opacity div
$('INPUT', $controlOpacity).change(function() {

    // how can I add another 5 seconds to setTimeout function via this function?
    removeOpacity();
});