JQuery расширить функцию setTimeout при изменении ввода - PullRequest
0 голосов
/ 27 октября 2018

Я пытаюсь добавить дополнительное время к setTimeout(), который был запущен с помощью отдельной функции .on('click').

Пожалуйста, следуйте моему описанию кода, чтобы понять, что происходит

// 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?

});

Поэтому, когда сработает моя функция изменения ввода, я хочу добавить еще 5 секунд к функции setTimeout, которая в данный момент работает через функцию .on('click')

Я уверен, что есть очевидноеспособ сделать это, но какое самое чистое решение jQuery для этого?

Спасибо

Ответы [ 2 ]

0 голосов
/ 27 октября 2018

Аналогичный ответ на 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();
});
0 голосов
/ 27 октября 2018

Вы не можете изменить время ожидания текущего 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);
});

Если невозможно вызвать событие change, когда класс open отсутствует, тогда это становится еще проще, поскольку не нужно будет проверять, работает ли таймаут или нет:

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